Hum*_*mad 5 java multithreading race-condition
我有一个简单的TestThreadClientMode
类来测试竞争条件.我尝试了两次尝试:
System.out.println(count);
在第二个线程中使用注释运行以下代码时,输出为:OS: Windows 8.1
flag done set true
...
第二个线程永远活着.因为第二个线程永远不会看到done
由主线程设置为true 的标志的更改.
当我取消注释System.out.println(count);
输出时:
OS: Windows 8.1
0
...
190785
190786
flag done set true
Done! Thread-0 true
程序在1秒后停止.
怎么System.out.println(count);
让第二个线程看到变化done
?
public class TestThreadClientMode {
private static boolean done;
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
public void run() {
int count = 0;
while (!done) {
count ++;
//System.out.println(count);
}
System.out.println("Done! " + Thread.currentThread().getName() + " " + done);
}
}).start();
System.out.println("OS: " + System.getProperty("os.name"));
Thread.sleep(1000);
done = true;
System.out.println("flag done set true ");
}
}
Run Code Online (Sandbox Code Playgroud)
这是内存一致性错误的一个很好的例子.简单地说,变量已更新,但第一个线程并不总是看到变量变化.这个问题可以通过声明done
变量来解决volatile
:
private static volatile boolean done;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,对变量的更改对所有线程都是可见的,程序总是在一秒后终止.
更新:似乎使用System.out.println
确实解决了内存一致性问题 - 这是因为print函数使用了实现同步的底层流.同步建立了一个发生在之前的关系,如我链接的教程中所述,它与volatile变量具有相同的效果.(这个答案的详细信息.也可以归功于@Chris K指出流操作的副作用.)
归档时间: |
|
查看次数: |
1045 次 |
最近记录: |