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,会发生什么?在示例中…如何使内部地图正确“内存瘫痪”?
坦克!
汤姆
解决方法
如果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.
外部地图上的决赛就足够了.