首页 > 解决方案 > 两个并行线程的静态块执行可以异步发生吗

问题描述

我有以下一段代码。

在任何时候,i 的值打印是否仍为 0。对于上述执行,我无法重现它。但在生产代码中,我得到的值为 0。

我有一个带有静态初始化块的生产代码。不知何故,其中一种方法在静态块完成执行之前被执行。

class TestStatic {

    private int i = 0;

    public static TestStatic testStatic = null;

    static {
        testStatic = new TestStatic();
        try {
            BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\I338224\\Documents\\temp\\src\\Test.xml"));
            final StringBuilder builder = new StringBuilder();
            final DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            docBuilderFactory.setIgnoringElementContentWhitespace(true);
            docBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
            DocumentBuilder docBuilder = null;
            docBuilder = docBuilderFactory.newDocumentBuilder();
            for(long i=0;i<1000000000;i++);
            Document d = docBuilder.parse("C:\\Users\\I338224\\Documents\\temp\\src\\Test.xml");
            reader.lines().forEach(line -> builder.append(line).append("\n"));
            System.out.println(builder.length());
            testStatic.i = 5;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
    }

    public static TestStatic getInstance(){
        return testStatic;
    }

    public void display(){
        System.out.println(i);
    }
}

public class Test {

    public static void main(String[] args) {

        Runnable r = () -> {
            TestStatic.getInstance().display();
        };
        Runnable r2 = () -> {
            TestStatic.getInstance().display();
        };
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r2);
        t1.start();
        t2.start();
    }
}

预期的结果是为 i 打印的值应该是 5。但它是 0。

标签: javastatic

解决方案


以下是您的代码的mcve只有当您取消评论
时,它才会打印出 0 :if(true) throw new IllegalStateException("Exception");

import java.util.concurrent.TimeUnit;

class TestStatic {

    private int i = 0;
    public static TestStatic testStatic = null;

    static {
        testStatic = new TestStatic();
        try {
            TimeUnit.SECONDS.sleep(1);
            //if(true) throw new IllegalStateException();
            testStatic.i = 5;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static TestStatic getInstance(){
        return testStatic;
    }

    public void display(){
        System.out.println(i);
    }
}

public class Test {

    public static void main(String[] args) {
        new Thread(() -> TestStatic.getInstance().display()).start();
        new Thread(() -> TestStatic.getInstance().display()).start();
    }
}

推荐阅读