新线程是否对所有其他线程先前对共享对象的操作具有完整的内存可见性?
Does a new thread have full memory-visibility of all other threads' previous actions on shared objects?
我有线程 A 维护数据结构(添加、删除、更改 ConcurrentHashMap 中的值)。
我有线程 B 侦听套接字,偶尔会创建线程 C 来处理新的客户端连接。
所有线程 Cs 只会从线程 A 维护的 ConcurrentHashMap 中读取(永远不要更新它)。
线程 C 是否保证看到线程 A 在 ConcurrentHashMap[= 上执行的所有更新32=],在线程 C 由线程 B?
创建/启动之前
(编辑最后一句以使问题更清楚:只关心 ConcurrentHashMap 的更新。)
是的,如docs所述:
Retrievals reflect the results of the most recently completed update
operations holding upon their onset. (More formally, an update
operation for a given key bears a happens-before relation with any
(non-null) retrieval for that key reporting the updated value.)
是,如果 ConcurrentHashMap
对象是全局共享的或 passed/shared to/with thread C
。
Is thread C guaranteed to see all updates that were performed by thread A before thread C was created/ started by thread B?
一般(比如用普通的HashMap
),没有
但是(一般来说)如果线程 C 是由线程 A 创建的,那么答案是肯定的。
(一个线程在线程对象上调用 start()
与新线程的 run()
方法开始之间存在 happens-before 关系.但是你引入了第三个线程......并且没有描述任何会给你一个happens-before从A到B再到C的链。)
但是,您在这里谈论的是 ConcurrentHashMap
,并发映射具有先天的内存一致性:
"Memory consistency effects: As with other concurrent collections, actions in a thread prior to placing an object into a ConcurrentMap
as a key or value happen-before actions subsequent to the access or removal of that object from the ConcurrentMap
in another thread."
(来自ConcurrentMap
javadoc.)
因此,对于任何多个线程共享一个 ConcurrentHashMap
的情况,只读线程保证可以看到另一个线程所做的更新......模数迭代器的记录行为。
你的短语
performed by thread A before thread C was created/ started by thread B?
处理定义不明确的概念,因为 Java 内存模型不提供任何基于时间顺序的保证。您必须通过程序顺序或同步顺序确保 happens-before 排序,而您似乎两者都没有。
所以,用 "no" 来回答你的问题是错误的,因为这个问题有一个错误的隐藏假设。
我是新手,我想补充一些东西,Dariusz 你不认为我们可以使用 volatile 修饰符更新值吗?
如果我错了请纠正我 volatile 变量总是 return 它的更新值。
我有线程 A 维护数据结构(添加、删除、更改 ConcurrentHashMap 中的值)。
我有线程 B 侦听套接字,偶尔会创建线程 C 来处理新的客户端连接。
所有线程 Cs 只会从线程 A 维护的 ConcurrentHashMap 中读取(永远不要更新它)。
线程 C 是否保证看到线程 A 在 ConcurrentHashMap[= 上执行的所有更新32=],在线程 C 由线程 B?
创建/启动之前(编辑最后一句以使问题更清楚:只关心 ConcurrentHashMap 的更新。)
是的,如docs所述:
Retrievals reflect the results of the most recently completed update operations holding upon their onset. (More formally, an update operation for a given key bears a happens-before relation with any (non-null) retrieval for that key reporting the updated value.)
是,如果 ConcurrentHashMap
对象是全局共享的或 passed/shared to/with thread C
。
Is thread C guaranteed to see all updates that were performed by thread A before thread C was created/ started by thread B?
一般(比如用普通的HashMap
),没有
但是(一般来说)如果线程 C 是由线程 A 创建的,那么答案是肯定的。
(一个线程在线程对象上调用 start()
与新线程的 run()
方法开始之间存在 happens-before 关系.但是你引入了第三个线程......并且没有描述任何会给你一个happens-before从A到B再到C的链。)
但是,您在这里谈论的是 ConcurrentHashMap
,并发映射具有先天的内存一致性:
"Memory consistency effects: As with other concurrent collections, actions in a thread prior to placing an object into a
ConcurrentMap
as a key or value happen-before actions subsequent to the access or removal of that object from theConcurrentMap
in another thread."
(来自ConcurrentMap
javadoc.)
因此,对于任何多个线程共享一个 ConcurrentHashMap
的情况,只读线程保证可以看到另一个线程所做的更新......模数迭代器的记录行为。
你的短语
performed by thread A before thread C was created/ started by thread B?
处理定义不明确的概念,因为 Java 内存模型不提供任何基于时间顺序的保证。您必须通过程序顺序或同步顺序确保 happens-before 排序,而您似乎两者都没有。
所以,用 "no" 来回答你的问题是错误的,因为这个问题有一个错误的隐藏假设。
我是新手,我想补充一些东西,Dariusz 你不认为我们可以使用 volatile 修饰符更新值吗?
如果我错了请纠正我 volatile 变量总是 return 它的更新值。