我需要volatile关键字吗?(JAVA)

Aft*_*ess 3 java multithreading volatile

我只需要如果将多个线程读取它来标记字段挥发的同时

那么线程A改变字段值的场景怎么样呢?线程B在保证线程A完成之后对它进行评估呢?

在我的场景中,是否存在之前发生的关系(没有volatile关键字)?

War*_*Dew 5

您需要使用volatile关键字或其他一些同步机制来强制执行"之前发生"关系,以保证变量在除写入它之外的线程中的可见性.没有这样的同步,一切都被视为"同时"发生,即使它不是由挂钟时间.

在您的特定示例中,没有同步可能发生的一件事是线程A写入的值永远不会从缓存刷新到主内存,线程B在另一个处理器上执行,永远不会看到线程A写入的值.

当你处理线程时,挂钟时间没有任何意义.如果希望数据在线程之间正确传递,则必须正确同步.没有正确同步的快捷方式,以后不会让您头疼.

在原始问题的情况下,可以通过使用volatile关键字,使用synchronized块或通过将正在读取变量值join()的线程的线程用于写入变量的线程来实现正确同步.

编辑: 响应您的注释,a Future具有内部同步,以便在调用返回时调用Future上的get()建立"之前发生"关系,这样也可以实现正确的同步.

  • 只有一个重要的说明:您不需要线程B在另一个处理器上运行以体验内存可见性问题(换句话说,这也可能发生在单核CPU上).一个实际的原因是JIT/Hotspot优化导致代码在CPU寄存器中保留某些值而无需读取或写入存储器.您需要正确的*before-before*关系来间接告诉优化器限制. (2认同)