ConcurrentHashMap和HashTable一样是线性安全的,但ConcurrentHashMap的性能要优于HashTable,因为ConcurrentHashMap加锁的粒度是要小于HashTable的,HashTable虽然是线性安全的,但HashTable在进行写和删除操作的时候,HashTable整个都加上了锁,只能单线程进行操作,,而不能同时有多个线程进行写和删除操作,ConcurrentHashMap在进行写和删除操作的时候是将锁加在Segment上的,一个ConcurrentHashMap中有多个Segment,只要多个线程不同时在一个Segment中进行操作ConcurrentHashMap就是线性安全的。在这里可以将Segment看成HashTable
一.ConcurrentHashMap的数据结构
ConcurrentHashMap的基本数据结构是由一个存储Segment的数组构成的。而Segment又是由一个存储HashEntry的数组构成的。HashEntry中就是存储着key-value样式的值。
ConcurrentHashMap的源码
/**
* The segments, each of which is a specialized hash table.
*/
final Segment<K,V>[] segments;
Segment的数据结构源码
static final class Segment<K,V> extends ReentrantLock implements Serializable {
transient volatile HashEntry<K,V>[] table;
transient int count;
transient int modCount;
transient int threshold;
final float loadFactor;
}
table:用来存储HashEntry元素的数组。
count:用来记录segment中的HashEntry的个数。
modCount:记录对这个segment进行写和删除操作的次数。
threshold:segment的阈值,当segment中的元素个数超过这个值后需要进行扩容。
loadFactor:加载因子,用于确定threhold。
HashEntry的数据结构
static final class HashEntry<K,V> {
final int hash;
final K key;
volatile V value;
volatile HashEntry<K,V> next;
HashEntry(int hash, K key, V value, HashEntry<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
}
可以看到HashEntry的一个特点,除了value以外,其他的几个变量都是final的,这样做是为了防止链表结构被破坏,出现ConcurrentModification的情况。
今天本来想把这把Java集合系列的博客写完的,在网上也看了一些ConcurrentHashMap的文章,但是打开ConcurrentHashMap的源码一看,发现和网上的源码差别挺大的,看了一下源码,有很多地方看不懂得,想写却写不出来,挺失落的。这将是我Java集合系列的最后一篇博客了,至于TreeMap,我看了一下,挺复杂的,以我的水平还不能写出来,只能自己下去看看,将里面的大体原理弄明白。后面将会对Spring源码进行学习。希望自己能坚持下来。
好的ConcurrentHashMap源码文章
http://www.iteye.com/topic/1103980
http://www.iteye.com/topic/344876
http://www.cnblogs.com/yydcdut/p/3959815.html