2012-08-17 54 views
0

您可以确保一个线程对某个变量所做的更改可以在其他线程上看到,方法是将该变量设置为volatile,或者让这两个线程同步某些内容。如果被改变的东西是一个java.util.ConcurrentHashMap,通过声明持有这张地图的变量的类型为volatile,或者读者访问地图(比如说通过myMap.values())来获取无论如何最新的可能观点?对于上下文,我有一个沉重的阅读,轻写作场景,我将lock free read solution切换到ConcurrentHashMap。如何获取ConcurrentHashMap的最新视图?

+0

声明字段'volatile'不是你想要的,因为你并没有修改字段值本身。查询地图会给出最新的结果。 – oldrinb 2012-08-17 07:26:32

+0

正确,我认为这也适用于AtomicReference。引用不是线程本地对所引用的东西没有影响,在这种情况下是地图。 – MilesHampson 2012-08-17 09:40:48

+0

是正确的,因为该字段的值永远不会改变,并且集合的所有内存一致性都是由'ConcurrentHashMap'内部完成的。 – oldrinb 2012-08-17 18:39:22

回答

3

ConcurrentHashMap保证写入和后续读取之间有一个发生之前的关系。所以是的,当您阅读(获取)时,您会看到最近发生的“已提交”更改(put已返回)。

注意:这不适用于javadoc中解释的迭代器。

2

变量“保存”地图是指向地图对象的引用或指针(分别(简化为)存储地图的内存地址)。使其变为易失性只会影响指针,而不会影响地图对象本身。只要您始终使用相同的Map-Object并确保地图在线程使用之前完全初始化,则不必使用“volatile引用”。并发性在并发哈希映射中透明地处理。

1

所有你需要做的就是确保持有地图的引用是最终的,所以你得到一个最终的场篱笆,保证你看到一个正确初始化的地图,并且引用本身没有改变。

正如其他人指出的那样,ConcurrentHashMap将保证在内部写入之前的可见性/发生 - 因为所有java.util.concurrent.*集合都这样做。但是,您应该使用ConcurrentMap接口上公开的条件写入来避免写入中的数据争用。

+0

*“您所需要做的就是确保持有地图的参考文件是最终的”*我认为这不是必需的。 – assylias 2012-08-17 09:34:31

+0

制作引用最终确实在JMM下具有保证非空引用将处于构建后状态的效果。 ConcurrentHashMap已经在内部做了正确的事情,所以你永远不会有可见性问题,但有人可能仍然会改变引用本身,所以最终确保正确性仍然有用。 – 2012-08-20 01:03:01

+0

这是一个很好的观点。 – assylias 2012-08-20 06:18:20