Java并发:“级联”变量中的易失性与最终性?

前端之家收集整理的这篇文章主要介绍了Java并发:“级联”变量中的易失性与最终性?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
final Map<Integer,Map<String,Integer>> status = new ConcurrentHashMap<Integer,Integer>>();
Map<Integer,Integer>> statusInner = new ConcurrentHashMap<Integer,Integer>>();
status.put(key,statusInner);

同样的

volatile Map<Integer,statusInner);

如果内部Map由不同的线程访问?

或者甚至是这样的要求:

volatile Map<Integer,Integer>>();
volatile Map<Integer,statusInner);

如果它不是一个“级联”地图,那么final和volatile最终会产生同样的效果,即所有线程总是看到Map的正确内容……但是如果Map iteself包含一个map,会发生什么?在示例中…如何使内部地图正确“内存瘫痪”?

坦克!
汤姆

解决方法

volatile仅影响其他线程读取其附加变量值的能力.它决不会影响另一个线程查看地图的键和值的能力.例如,我可以有一个volatile int [].如果我改变参考 – 即.如果我更改它指向的实际数组 – 其他线程读取数组保证看到该更改.但是,如果我更改数组的第三个元素,则不会进行此类保证.

如果status为final,则包含类的构造会创建与任何后续读取之前发生的关系,因此它们可以查看status的值.同样,对volatile变量的任何读取都保证会看到对它的最新引用赋值.这与你经常交换实际地图不同,更像是你只是改变键而整个地图对象保持不变.

对于这个问题,我们需要查阅ConcurrentHashMap的文档:

Retrieval operations (including get)
generally do not block,so may overlap
with update operations (including put
and remove). Retrievals reflect the
results of the most recently completed
update operations holding upon their
onset.

这有点奇怪的措辞,但要点是任何get操作,其开始是在一些put操作的返回之后保证看到put的结果.所以你甚至不需要在外图上使用volatile; JLS:

A thread that can only see a reference
to an object after that object has
been completely initialized is
guaranteed to see the correctly
initialized values for that object’s
final fields.

摘要

外部地图上的决赛就足够了.

猜你在找的Java相关文章