是否为非易失性var保证了顺序线程运行的可见性?

时间:2019-05-02 18:25:12

标签: java multithreading atomic volatile

我已阅读以下参考文献:

http://tutorials.jenkov.com/java-concurrency/volatile.html

https://www.geeksforgeeks.org/volatile-keyword-in-java/

https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html

但是,我仍然不清楚在以下情况下的预期行为:

  1. 我有一个线程池,可以在其中重新使用线程。
  2. 我有一个非易失性var,可以通过该线程池的不同线程来访问。
  3. 线程按顺序运行。(是的,它们可以在一个线程中运行。但是,仅在这种情况下。所以,不要问为什么不使用一个线程)

我不清楚的部分是。我是否仍然需要volatile以确保对下一个线程执行可见在前一个线程中所做的更改。

就像Java Flash线程在每次执行后将本地缓存缓存到内存一样吗?

该线程是否在每次执行前重新加载本地缓存?

它总是抱怨有没有引用的代码部分。因此,我必须这样做。请帮忙解决。

2 个答案:

答案 0 :(得分:1)

Java内存模型设计可以回答您的问题: 在Java内存模型中,易失性字段在写入存储对象后插入存储屏障,在读取存储对象前插入加载屏障。合格的类的最终字段在初始化后插入了存储屏障,以确保在对对象的引用可用时构造函数完成后,这些字段就可见。

请参见https://dzone.com/articles/memory-barriersfences

换句话说:当线程尝试从易失性变量中读取时,JMM会强制拥有此内存区域的所有CPU从本地CPU的高速缓存写回内存。然后,如有必要,CPU会将其值加载到本地缓存中。

  

我不清楚的部分是。我是否仍然需要volatile以确保对下一个线程执行可见在前一个线程中所做的更改。

是,不是。 Volatile关键字仅用于使变量的值对其他线程可见。但是,如果此时仅需要一个线程读写,则需要同步。如果您只需要提供可见性= volatile关键字就足够了。

如果您不使用volatile关键字并通过线程共享值,则它可能不是最新的,甚至已损坏。对于LONG类型的Java,按32位执行2次写操作,它们不是原子的。假设另一个线程可以读取两次写入之间的值。

答案 1 :(得分:1)

线程是否按顺序并行运行无关紧要,如果不使用volatile关键字,则无法保证可见性。这意味着不能保证另一个线程会看到最新的副本,因为该线程可以从寄存器中读取值。