加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-14 23:57:30 所属栏目:Java 来源:网络整理
导读:是 final MapInteger,MapString,Integer status = new ConcurrentHashMapInteger,Integer();MapInteger,Integer statusInner = new ConcurrentHashMapInteger,Integer();status.put(key,statusInner); 同样的 volatile MapInteger,statusInner); 如果内部Map
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.

摘要

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读