我需要 volatile 关键字吗? (Java)
Do I need the volatile keyword? (Java)
如果多个线程同时读取字段,是否只需要将字段标记为易失性?
线程A修改了某个字段的值,线程B在保证线程A完成后才求值的场景呢?
在我的场景中,是否强制执行了先行发生关系(没有 volatile 关键字)?
您需要使用 volatile 关键字或其他一些同步机制来强制执行 "happens before" 关系,以保证变量在写入变量的线程以外的线程中的可见性。没有这样的同步,一切都被视为正在发生 "at the same time",即使它不是按挂钟时间发生的。
在您的特定示例中,没有同步可能会发生的一件事是线程 A 写入的值永远不会从缓存刷新到主内存,并且线程 B 在另一个处理器上执行并且永远不会看到线程 A 写入的值.
当您处理线程时,挂钟时间毫无意义。如果您希望数据在线程之间正确传递,则必须正确同步。正确同步没有捷径,以后不会让您头疼。
对于您原来的问题,可以通过使用 volatile
关键字、使用 synchronized
块或让线程读取值来实现适当的同步变量的 join()
写入变量的线程。
编辑: 为回应您的评论,Future
具有内部同步,因此在 Future 上调用 get() 会建立 "happens before" 关系调用 returns,这样也可以实现正确的同步。
不,你不需要volatile
...
is there a happens-before relationship enforced (without the volatile keyword)?
...但是您的代码需要做 某事 才能建立 "happens-before."
如果(并且 仅 如果)你的代码做了一些 "Java Language Specification" (JLS) 表示将建立 "happens-before."
What about the scenario where Thread A changes the value of a field, and Thread B evaluates it after Thread A is guaranteed to have completed?
取决于您所说的 "guaranteed." 的意思 如果 "guaranteed" 的意思是 "established happens-before," 那么您的代码将按预期工作。
您可以保证的一种方法是让线程 B 调用 threadA.join()
。 JLS 保证如果线程 B 调用 threadA.join()
,那么线程 A 所做的一切都必须 "happen before" join()
调用 returns.
如果线程 B 仅在加入线程 A 后访问它们,则不需要任何共享变量 volatile
。
您可以选择一个可用的选项来达到相同的目的。
- 您可以使用
volatile
强制所有线程从主内存中获取变量的最新值。
- 您可以使用
synchronization
来保护关键数据
- 可以使用
Lock
API
- 您可以使用
Atomic
个变量
请参阅此文档 page 了解高级并发构造。
看看相关的SE问题:
Avoid synchronized(this) in Java?
What is the difference between atomic / volatile / synchronized?
如果多个线程同时读取字段,是否只需要将字段标记为易失性?
线程A修改了某个字段的值,线程B在保证线程A完成后才求值的场景呢?
在我的场景中,是否强制执行了先行发生关系(没有 volatile 关键字)?
您需要使用 volatile 关键字或其他一些同步机制来强制执行 "happens before" 关系,以保证变量在写入变量的线程以外的线程中的可见性。没有这样的同步,一切都被视为正在发生 "at the same time",即使它不是按挂钟时间发生的。
在您的特定示例中,没有同步可能会发生的一件事是线程 A 写入的值永远不会从缓存刷新到主内存,并且线程 B 在另一个处理器上执行并且永远不会看到线程 A 写入的值.
当您处理线程时,挂钟时间毫无意义。如果您希望数据在线程之间正确传递,则必须正确同步。正确同步没有捷径,以后不会让您头疼。
对于您原来的问题,可以通过使用 volatile
关键字、使用 synchronized
块或让线程读取值来实现适当的同步变量的 join()
写入变量的线程。
编辑: 为回应您的评论,Future
具有内部同步,因此在 Future 上调用 get() 会建立 "happens before" 关系调用 returns,这样也可以实现正确的同步。
不,你不需要volatile
...
is there a happens-before relationship enforced (without the volatile keyword)?
...但是您的代码需要做 某事 才能建立 "happens-before."
如果(并且 仅 如果)你的代码做了一些 "Java Language Specification" (JLS) 表示将建立 "happens-before."
What about the scenario where Thread A changes the value of a field, and Thread B evaluates it after Thread A is guaranteed to have completed?
取决于您所说的 "guaranteed." 的意思 如果 "guaranteed" 的意思是 "established happens-before," 那么您的代码将按预期工作。
您可以保证的一种方法是让线程 B 调用 threadA.join()
。 JLS 保证如果线程 B 调用 threadA.join()
,那么线程 A 所做的一切都必须 "happen before" join()
调用 returns.
如果线程 B 仅在加入线程 A 后访问它们,则不需要任何共享变量 volatile
。
您可以选择一个可用的选项来达到相同的目的。
- 您可以使用
volatile
强制所有线程从主内存中获取变量的最新值。 - 您可以使用
synchronization
来保护关键数据 - 可以使用
Lock
API - 您可以使用
Atomic
个变量
请参阅此文档 page 了解高级并发构造。
看看相关的SE问题:
Avoid synchronized(this) in Java?
What is the difference between atomic / volatile / synchronized?