ConcurrentHashMap 实现机制

gongruitao 2019-04-16

ConcurrentHashMap 实现机制

Hashtable中采用的锁机制是一次锁住整个hash表,从而同一时刻只能由一个线程对其进行操作;

而ConcurrentHashMap中则是 一次锁住一个桶。

ConcurrentHashMap默认将hash表分为16个桶,诸如get, put, remove等常用操作只锁当前需要用到的桶。

这样,原来只能一个线程进入,现在却能同时有16个写线程执行,并发性能的提升是显而易见的。

上面说到的16个线程指的是写线程,而读操作大部分时候都不需要用到锁。只有在size等操作时才需要锁住整个hash表。

ConcurrentHashMap 实现机制

ConcurrentHashMap和Hashtable主要区别就是围绕着锁的粒度以及如何锁,可以简单理解成把一个大的HashTable分解成多个,形成了锁分离。如图:

ConcurrentHashMap 实现机制

而Hashtable的实现方式是---锁整个hash表。

从JDK1.2起,就有了HashMap,HashMap不是线程安全的,因此多线程操作时需要格外小心。

在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,从此Map也有安全的了。

ConcurrentHashMap具体是怎么实现线程安全的呢,肯定不可能是每个方法加synchronized,那样就变成了HashTable。

从ConcurrentHashMap代码中可以看出,它引入了一个“分段锁”的概念,具体可以理解为把一个大的Map拆分成N个小的HashTable,根据key.hashCode()来决定把key放到哪个HashTable中。

在ConcurrentHashMap中,就是把Map分成了N个Segment,put和get的时候,都是现根据key.hashCode()算出放到哪个Segment中:

ConcurrentHashMap 实现机制

ConcurrentHashMap中默认是把segments初始化为长度为16的数组。

以上就是ConcurrentHashMap的工作机制,通过把整个Map分为N个Segment(类似HashTable),可以提供相同的线程安全,但是效率提升N倍,默认提升16倍。

可以进一步阅读另外一篇文章:《ConcurrentHashMap原理分析

相关推荐