基于Java ConcurrentHashMap的研究
2023-09-08
来源:汇智旅游网
AP PLICATION● 一 基于J a va C o n cu rre n t H a s h M a 的研究 摘要:ConcurrentHashMap是Java的util.concurrent 包的一部分,它提供比Hashtable或者synchronizedMap更 高程度的并发性。而且,对于大多数成功的get()操作它 会设法避免完全锁定,其结果就是使得在不损失线程安全的 情况下并发应用程序有着非常好的吞吐量 本文重点介绍 ConcurrentHashMap的6种特性. 关键词:Java、线程、ConcurrentHashMap、并发 1 不用锁定遍历数据结构 与Hashtable或者典型的锁池Map实现不同, ConcurrentHashMap.get()操作不一定需要获取与相关 bucket相关联的锁。如果不使用锁定,那么实现必须有能力处 理它用到的所有变量的过时的或者不一致的值,比如说列表头 指针和Map.Entry元素的域。大多并发类使用同步来保证独占 式访问一个数据结构。ConcurrentHashMap没有采用独占性 和一致性,它使用的链表是经过精心设计的,所以其实现可以 检测到它的列表是否一致或者已经过时。 2、使用不变性 不一致性的一个重要来源是可以避免得,其方法是使Entry 元素接近不变性一一除了值字段(它们是易变的)之外,所有 字段都是final的。这就意味着不能将元素添加到hash链的中 间或末尾,或者从hash链的中间或末尾删除元素一一而只能从 hash链的开头添加元素,并且删除操作包括克隆整个链或链的 一部分并更新列表的头指针。 检索操作 检索操作首先为目标bucket查找头指针(是在不锁定的 情况下完成的,所以说可能是过时的),然后在不获取bucket 锁的情况下遍历bucket链。如果它不能发现要查找的值,就 会同步并试图再次查找条目。 3 删除操作 因为一个线程可能看到hash链中链接指针的过时的值,简 单地从链中删除一个元素不足以保证其他线程在进行查找的时 候不继续看到被删除的值。相反,从清单3我们可以看到,删 除操作分两个过程一一首先找到适当的EnfⅣ对象并把其值字段 设为null,然后对链中从头元素到要删除的元素的部分进行克隆, 再连接到要删除的元素之后的部分。因为值字段是易变的,如 果另外一个线程正在过时的链中查找那个被删除的元素,它会 立即看到一个空值,并知道使用同步重新进行检索。最终,原 始hash链中被删除的元素将会被垃圾收集。 4,插入和更新操作 put()的实现很简单。像remove[)一样,put()会在执行 期间保持bucket锁,但是由于put()并不是都需要获取锁,所 以这并不一定会阻塞其他读线程的执行(也不会阻塞其他写线 程访问别的bucket)。它首先会在适当的hash链中搜索需要 的键值。 动态调整大小 随着map中元素数目的增长,hash链将会变长,因此检 索时间也会增加。从某种意义上说,增加bucket的数目和重排 其中的值是非常重要的。在有些像Hashtable之类的类中,这 很简单,因为保持一个应用到整个map的独占锁是可能的。在 ConcurrentHashMap中,每次一个条目插入的时候,如果链 的长度超过了某个阈值,链就被标记为需要调整大小。当有足 够多的链被标记为需要调整大小以后,ConcurrentHashMap 就使用递归获取每个bucket上的锁并重排每个bucket中的元 素到一个新的、更大的hash表中。多数情况下,这是自动发生 的,并且对调用者透明。 结束语 ConcurrentHashMap对于很多并发应用程序来说是一个 非常有用的类,而且对于理解JMM何以取得较高性能的微妙细 节是一个很好的例子。ConcurrentHashMap是编码的经典, 需要深刻理解并发和JMM才能够写得出。嘻p 参考文献: 【l】LEWIS B.Java多线程编程[M】.北京:电子工业出版社,2000 [2l David Y W Park,Ulrich Stem,Jens U Skakkebak,et a1. Java model checking[e1.Proceedings ASE.2o0O. [3J Goetz B,Peierls T,Bloch J.Java Concurrency in Practice IM1.Addison Wesley Professional,2006,1一l1 【4】Bruening D L.Systematic Testing of Multithrea(ted Java Programs lM】.MIT Press,l999,3—15. 作者简介: 李大鹏唐山学院计算中心 黄金红唐山学院经济管理系 2010.口5 蜀 67