快速业务通道

Java理论与实践: 构建一个更好的HashMap - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-22
设计的,所以其实现可以 检测 到它的列表是否一致或者已经过时。如果 它检测到它的列表出现不一致或者过时,或者干脆就找不到它要找的条目,它就 会对适当的bucket 锁进行同步并再次搜索整个链。这样做在一般的情况下可以 优化查找,所谓的一般情况是指大多数检索操作是成功的并且检索的次数多于插 入和删除的次数。

使用不变性

不一致性的一个重要来源是可以避免得,其方法是使 Entry 元素接近不变性 ――除了值字段(它们是易变的)之外,所有字段都是 final的。这就意味着不 能将元素添加到 hash 链的中间或末尾,或者从 hash 链的中间或末尾删除元素 ――而只能从 hash 链的开头添加元素,并且删除操作包括克隆整个链或链的一 部分并更新列表的头指针。所以说只要有对某个 hash 链的一个引用,即使可能 不知道有没有对列表头节点的引用,您也可以知道列表的其余部分的结构不会改 变。而且,因为值字段是易变的,所以能够立即看到对值字段的更新,从而大大 简化了编写能够处理内存潜在过时的 Map的实现。

新的 JMM 为 final 型变量提供初始化安全,而老的 JMM 不提供,这意味着 另一个线程看到的可能是 final 字段的默认值,而不是对象的构造方法提供的 值。实现必须能够同时检测到这一点,这是通过保证 Entry 中每个字段的默认 值不是有效值来实现的。这样构造好列表之后,如果任何一个 Entry 字段有其 默认值(零或空),搜索就会失败,提示同步 get() 并再次遍历链。

检索操作

检索操作首先为目标 bucket 查找头指针(是在不锁定的情况下完成的,所 以说可能是过时的),然后在不获取 bucket 锁的情况下遍历 bucket 链。如果 它不能发现要查找的值,就会同步并试图再次查找条目,如清单2所示:

清单2. ConcurrentHashMap.get() 实现

public Object get(Object key) {    int hash = hash(key);   // throws null pointer exception if key is null    // Try first without locking...    Entry[] tab = table;    int index = hash & (tab.length - 1);    Entry first = tab[index];    Entry e;    for (e = first; e != null; e = e.next) {     if (e.hash == hash && eq(key, e.key)) {      Object value = e.value;      // null values means that the element has been removed      if (value != null)       return value;      else       break;     }    }    // Recheck under synch if key apparently not there or interference    Segment seg = segments[hash & SEGMENT_MASK];    synchronized(seg) {     tab = table;     index = hash & (tab.length - 1);     Entry newFirst = tab[index];     if (e != null || first != newFirst) {      for (e = newFirst; e != null; e = e.next) {       if (e.hash == hash && eq(key, e.key))        return e.value;      }     }     return null;    }   }

Java理论与实践: 构建一个更好的HashMap(3)

时间:2010-12-21 IBM Brian Goetz

删除操作

因为一个线程可能看到 hash 链中链接指针的过时的值,简单地从链中删除 一个元素不足以保证其他线程在进行查找的时候不继续看到被删除的值。相反, 从清单3我们可以看到,删除操作分两个过程――首先找到适当的 Entry 对象并 把其值字段设为 null ,然后对链中从头元素到要删除的元素的部分进行克隆, 再连接到要删除的元素之后的部分。因为值字段是易变的,如果另外一个线程正 在过时的链中查找那个被删除的元素,它会立即看到一个空值,并知道使用同步

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号