gpt4 book ai didi

java - 如何模拟构造函数竞争条件?

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:58:33 24 4
gpt4 key购买 nike

我正在阅读“Java 并发实践”并查看第 51 页的示例代码。

这表明,如果一个线程引用了一个共享对象,那么其他线程可能能够在构造函数完成执行之前访问该对象。

我已经尝试将其付诸实践,因此我编写了这段代码,认为如果我运行它的次数足够多,就会发生 RuntimeException("World is f*cked")。但它没有做。

这是不是 Java 规范没有保证某些东西但我的特定 java 实现为我保证它的情况? (Java 版本:Ubuntu 上的 1.5.0)还是我看错了书中的内容?

代码:(我期待一个异常,但它永远不会被抛出)

public class Threads {
private Widgit w;

public static void main(String[] s) throws Exception {
while(true){
Threads t = new Threads();
t.runThreads();
}
}

private void runThreads() throws Exception{
new Checker().start();
w = new Widgit((int)(Math.random() * 100) + 1);
}

private class Checker extends Thread{
private static final int LOOP_TIMES = 1000;

public void run() {
int count = 0;
for(int i = 0; i < LOOP_TIMES; i++){
try {
w.checkMe();
count++;
} catch(NullPointerException npe){
//ignore
}
}
System.out.println("checked: "+count+" times out of "+LOOP_TIMES);
}
}

private static class Widgit{
private int n;
private int n2;

Widgit(int n) throws InterruptedException{
this.n = n;
Thread.sleep(2);
this.n2 = n;
}

void checkMe(){
if (n != n2) {
throw new RuntimeException("World is f*cked");
}
}
}

}

最佳答案

在构造函数完成之前不要发布引用,像这样更改 Widgit:

private class Widgit{ // NOTE: Not class is not static anymore
private int n;
private int n2;

Widgit(int n) throws InterruptedException{
this.n = n;
w = this; // publish reference
Thread.sleep(2);
this.n2 = n;
}

void checkMe(){
if (n != n2) {
throw new RuntimeException("World is f*cked");
}
}

现在应该抛出。

编辑:您还应该将 Widgit 字段声明为 volatile:

 private volatile Widgit w;

关于java - 如何模拟构造函数竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2614066/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com