这个程序的答案必须在5秒后完成“改变完成”,但我得到“改变完成”和“完成”。我没有getDone方法同步。我有什么想法为线程完成处理。
public class Main {
private static boolean done = false;
private static int count;
public static void main(String[] args)throws InterruptedException {
new Thread(() -> {
while (!getDone()) {
count = count + 1;
}
System.out.println("DONE!!!!");
}).start();
Thread.sleep(5000);
System.out.println("Changing done");
synchronized (Main.class) {
done = true;
}
}
public static boolean getDone() {
return done;
}
}
答案 0 :(得分:5)
如果您未正确同步done
的访问权限,则表示您的代码可能失败,即线程可能看不到更新的值。
这并不意味着除非正确同步,否则保证值不可见。因此,在许多情况下,对done
的写入仍然可见(在许多情况下,破坏的代码仍然有效,这使得并发编程变得更加困难)。它无法保证在每种情况下都能正常工作。
答案 1 :(得分:1)
我没有将getDone方法同步化。我有什么想法让线程完成处理。
正如您所提到的,在您的旋转线程和主线程看到的done
之间没有明确的内存同步。虽然主线程在退出synchronized
块时穿过写入内存屏障,但旋转线程没有明确的读取内存屏障。
但是,线程有很多方法可以查看更新的信息。如果操作系统将线程交换出正在运行的处理器,则缓存的内存可能会丢失,因此当线程被交换回来时,它将从中央内存请求done
并将看到更新。
此外,虽然您的示例代码没有显示,但是如果您调用其他synchronized
方法(例如System.out.println()
)或跨越其他内存屏障(访问另一个volatile