java - 两个并行线程的静态块执行可以异步发生吗
问题描述
我有以下一段代码。
在任何时候,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。
解决方案
以下是您的代码的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();
}
}
推荐阅读
- c# - 从 C# 保存到 SQL 中的 DATE 类型列 - Linq to SQL
- azure-devops - Azure DevOps YAML 构建管道卡在自托管代理上
- javascript - 数组未映射
- java - Wildfly 重启后起不来
- c# - 如何使用 c# regex 使用嵌套参数分割行?
- python - 改进这些 opencv 嵌套循环
- wordpress - 检索帖子数
- iis - Exchange 本地 OWA REST API 未正确处理 CORS 预检
- c# - 有没有办法限制脚本只能由 Unity 中的单个游戏对象使用?
- python - 如何编写正则表达式以返回由 OR 运算符分隔的两组字符之间的所有字符?