我对这样的代码片段感到困惑:
public class LearnTest {
private static boolean tag = true;
private static int i = 0;
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
while (tag) {
//System.out.println("ok");
i++;
}
}
}).start();
try {
Thread.sleep(1000);
}catch (Exception e) {
e.printStackTrace();
}
tag = false;
System.out.println(i);
}
}
在代码中,我们有一个 new-thread
和main-thread
.有关此代码的结果将是随机值 i
,并且new-thread
不会退出。因为new-thread
不会得到新的tag
值。
如果我们更改将用volatile
装饰的tag
的定义,它将打印一些i
值,new-thread
将退出。因为volatile
将保持所有线程的可见性。
但是当我不能为注释的代码行添加注释时,tag
不会被装饰女巫volatile
,它会打印一些"ok"并退出。
为什么?
我想Java的IO会做类似synchronized
的事情,它会强制new-thread
的tag
端值从主共享内存刷新。
这是科雷特?
如果没有volatile
,线程不能保证看到值的更改。它可能会看到它们。
在这种情况下,添加System.out.println()
(显然(会导致值从缓存中删除,因此它会在某个时候从主内存中获取。如果没有println()
值将保留在缓存中,您将获得无限(或至少很长(循环。
这是并发编程的一个困难,有时代码可能看起来工作正常,但没有办法确定它总是正常工作。