我对这样的代码段感到困惑:
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
值。
如果我们更改将使用tag
修饰的volatile
的定义,则会打印一些i
的值,new-thread
将退出。因为volatile
会保持所有主题的可见性。
但是,当我为评论的代码行添加注释时,tag
将不会被装饰为volatile
,它会打印一些“ok”并退出。
为什么?
我认为Java的IO会执行synchronized
之类的操作,它会强制tag
的{{1}}边值从主共享内存中刷新。
这是正确的吗?
答案 0 :(得分:0)
如果没有volatile
,则线程不会保证以查看对值的更改。 可以看到它们。
在这种情况下,在从缓存中删除的值中添加System.out.println()
结果(显然),因此它在某个时刻从主内存中获取。如果没有println()
,则值保留在缓存中,并且您将获得无限(或至少非常长)的循环。
这是并发编程的一个难点,有时代码可能出现才能正常工作,但是无法确定总是是否正常工作。