Java 新线程是否具有所有其他线程的完整内存可见性';以前对共享对象执行的操作?

Java 新线程是否具有所有其他线程的完整内存可见性';以前对共享对象执行的操作?,java,multithreading,concurrency,thread-safety,memory-model,Java,Multithreading,Concurrency,Thread Safety,Memory Model,我让线程A维护数据结构(添加、删除、更改ConcurrentHashMap中的值) 我让线程B监听套接字,偶尔创建线程C来处理新的客户端连接 所有线程Cs将只从线程A维护的ConcurrentHashMap中读取(从不更新) 线程C是否保证在线程B创建/启动线程C之前,在ConcurrentHashMap上查看线程A执行的所有更新 (编辑最后一句以使问题更清楚:只关心ConcurrentHashMap的更新。)是,如中所述: 检索反映最近完成的更新的结果 手术一开始就进行。(更正式地说,是更新

我让线程A维护数据结构(添加、删除、更改ConcurrentHashMap中的值)

我让线程B监听套接字,偶尔创建线程C来处理新的客户端连接

所有线程Cs将只从线程A维护的ConcurrentHashMap中读取(从不更新)

线程C是否保证在线程B创建/启动线程C之前,在ConcurrentHashMap上查看线程A执行的所有更新

(编辑最后一句以使问题更清楚:只关心ConcurrentHashMap的更新。)

是,如中所述:

检索反映最近完成的更新的结果 手术一开始就进行。(更正式地说,是更新 给定键的操作在与任何 (非空)检索报告更新值的键。)

是的,如中所述:

检索反映最近完成的更新的结果 手术一开始就进行。(更正式地说,是更新 给定键的操作在与任何 (非空)检索报告更新值的键。)


是,如果
ConcurrentHashMap
对象是全局共享的,或者传递给
线程C
或与之共享

是,如果
ConcurrentHashMap
对象是全局共享的,或者是传递/共享给
线程C

线程C是否保证在线程B创建/启动线程C之前看到线程A执行的所有更新

通常(例如,对于普通的
HashMap
),没有

但是(一般来说)如果线程C是由线程A创建的,那么答案是肯定的

(在一个线程对象上调用
start()
的一个线程与新线程的
run()
方法的开始之间有一个发生之前的关系。但是您已经引入了第三个线程…并且没有描述任何可以给您从a到B到C的发生之前链的内容。)


但是,您在这里谈论的是一个
ConcurrentHashMap
,并且并发映射具有固有的内存一致性:

“内存一致性影响:与其他并发集合一样,在将对象作为键或值放入
ConcurrentMap
之前,线程中的操作发生在另一个线程中从
ConcurrentMap
访问或删除该对象之后的操作之前。”

(从
ConcurrentMap

因此,对于多个线程共享
ConcurrentHashMap
的任何情况,只读线程都保证看到另一个线程所做的更新。。。对迭代器记录的行为进行模化

线程C是否保证在线程B创建/启动线程C之前看到线程A执行的所有更新

通常(例如,对于普通的
HashMap
),没有

但是(一般来说)如果线程C是由线程A创建的,那么答案是肯定的

(在一个线程对象上调用
start()
的一个线程与新线程的
run()
方法的开始之间有一个发生之前的关系。但是您已经引入了第三个线程…并且没有描述任何可以给您从a到B到C的发生之前链的内容。)


但是,您在这里谈论的是一个
ConcurrentHashMap
,并且并发映射具有固有的内存一致性:

“内存一致性影响:与其他并发集合一样,在将对象作为键或值放入
ConcurrentMap
之前,线程中的操作发生在另一个线程中从
ConcurrentMap
访问或删除该对象之后的操作之前。”

(从
ConcurrentMap

因此,对于多个线程共享
ConcurrentHashMap
的任何情况,只读线程都保证看到另一个线程所做的更新。。。对迭代器记录的行为进行模化。

您的短语

在线程B创建/启动线程C之前由线程A执行

处理定义不正确的概念,因为Java内存模型不提供任何基于时间顺序的保证。您必须确保在通过程序顺序或同步顺序进行排序之前发生错误,而您似乎两者都没有这样做

所以,用“不”回答你的问题是错误的,因为这个问题有一个错误的隐藏假设。

你的短语

在线程B创建/启动线程C之前由线程A执行

处理定义不正确的概念,因为Java内存模型不提供任何基于时间顺序的保证。您必须确保在通过程序顺序或同步顺序进行排序之前发生错误,而您似乎两者都没有这样做


所以,用“否”回答你的问题是错误的,因为这个问题有一个错误的隐藏假设。

我是新来的,我想补充一点,Dariusz你不认为对于更新的值,我们可以使用volatile修饰符吗


如果我错了,请纠正我。volatile变量总是返回其更新的值。

我是新手,我想添加一些东西,Dariusz您不认为对于更新的值,我们可以使用volatile修饰符吗


如果我错了,请纠正我。volatile变量始终返回其更新的值。

是,根据Java内存模型(q.v.)中的“发生在之前”的规定。基本上,您需要确保每个访问都是
同步的
java.util.concurrent
等效的