ConcurrentHashMap

来源:互联网 发布:sql 入门到精通 编辑:程序博客网 时间:2024/06/05 05:41


ConcurrentHashMap 提供了细粒度的加锁机制,如果这个map中有 n 个锁和 5n个元素,那第一个锁就负责第1个、第1+n个、第1+2n个.....元素的同步。

它允许任意数量的读线程并发访问。允许一定数量的写线程并发地修改。

在 org.apache.hadoop.mapreduce.v2.app.launcher.ContainerLauncherImpl 中包含一个 ConcurrentHashMap  变量 containers 用来存储 Container:

private ConcurrentHashMap<ContainerId, Container> containers =     new ConcurrentHashMap<ContainerId, Container>(); 
private Container getContainer(ContainerLauncherEvent event) {    ContainerId id = event.getContainerID();    Container c = containers.get(id);    if(c == null) {      c = new Container(event.getTaskAttemptID(), event.getContainerID(),          event.getContainerMgrAddress(), event.getContainerToken());      Container old = containers.putIfAbsent(id, c);      if(old != null) {        c = old;      }    }    return c;  }
getContainer这个方法不能加锁,不然 containers 企图用 ConcurrentHashMap  的高并发性就完全被屏蔽了。

既然不能加锁,不能保证 从 containers.get(id) 到  containers.putIfAbsent(id,c) 这个先判断,后操作的逻辑的原子性,那么它就不是线程安全的。

putIfAbsent 操作后就必须通过查看 old 是否为 null 再判断一下在当前线程对 containers get操作后,putIfAbsent操作前是否有其他线程对 containers 执行了

参数id相同的 putIfAbsent(id,c) 操作。

所以加上这个判断就可以了,没什么开销:

 if(old != null) {        c = old; }