concurrent包分析-ConcurrentMap及其实现类
2017-05-24 17:29
519 查看
concurrent包分析-ConcurrentMap及其实现类
ConcurrentMap有两个实现类,ConcurrentHashMap, ConcurrentSkipListMap。下面对这两个实现类进行分析。ConcurrentHashMap
通过分析Hashtable就知道,synchronized是针对整张Hash表的,即每次锁住整张表让线程独占,ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术。它使用了多个锁来控制对hash表的不同部分进行的修改。ConcurrentHashMap的结构可以用下图表示:ConcurrentHashMap中主要实体类就是三个:ConcurrentHashMap(整个Hash表),Segment(桶),HashEntry(节点),对应上面的图可以看出之间的关系。
初始化
//initialCapacity表示初始容量,默认16;loadFactor表示负载因子,默认0.75,用于扩容;concurrencyLevel表示并发级别,这个值用来确定Segment的个数,默认16。 public ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) { //合法性校验 if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0) throw new IllegalArgumentException(); if (concurrencyLevel > MAX_SEGMENTS) concurrencyLevel = MAX_SEGMENTS; // Find power-of-two sizes best matching arguments int sshift = 0; int ssize = 1; //保证concurrencyLevel取2的幂 while (ssize < concurrencyLevel) { ++sshift; ssize <<= 1; } //segmentShift和segmentMask分别表示段偏移量和段掩码 this.segmentShift = 32 - sshift; this.segmentMask = ssize - 1; if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; int c = initialCapacity / ssize; if (c * ssize < initialCapacity) ++c; int cap = MIN_SEGMENT_TABLE_CAPACITY; while (cap < c) cap <<= 1; // cap表示每个Segment的大小,ssize表示Segment的个数,这里分配了空间,并做了初始化。 Segment<K,V> s0 = new Segment<K,V>(loadFactor, (int)(cap * loadFactor), (HashEntry<K,V>[])new HashEntry[cap]); Segment<K,V>[] ss = (Segment<K,V>[])new Segment[ssize]; UNSAFE.putOrderedObject(ss, SBASE, s0); // ordered write of segments[0] this.segments = ss; }
put方法
public V put(K key, V value) { Segment<K,V> s; if (value == null) throw new NullPointerException(); int hash = hash(key); //确定Segment的位置 int j = (hash >>> segmentShift) & segmentMask; if ((s = (Segment<K,V>)UNSAFE.getObject // nonvolatile; recheck (segments, (j << SSHIFT) + SBASE)) == null) // in ensureSegment s = ensureSegment(j); return s.put(key, hash, value, false); }
这里的put委托给了Segment.put()实现。
final V put(K key, int hash, V value, boolean onlyIfAbsent) { //锁住Segment,这个就是ConcurrentMap比hashTable效率高的原因,因为锁的粒度小 HashEntry<K,V> node = tryLock() ? null : scanAndLockForPut(key, hash, value); V oldValue; try { HashEntry<K,V>[] tab = table; //获取是哪个HashEntry int index = (tab.length - 1) & hash; HashEntry<K,V> first = entryAt(tab, index); //查到就替换,查不到new一个HashEntry,放到链表头 for (HashEntry<K,V> e = first;;) { if (e != null) { K k; if ((k = e.key) == key || (e.hash == hash && key.equals(k))) { oldValue = e.value; if (!onlyIfAbsent) { e.value = value; ++modCount; } break; } e = e.next; } else { if (node != null) node.setNext(first); else node = new HashEntry<K,V>(hash, key, value, first); int c = count + 1; if (c > threshold && tab.length < MAXIMUM_CAPACITY) rehash(node); else setEntryAt(tab, index, node); ++modCount; count = c; oldValue = null; break; } } } finally { unlock(); } return oldValue; }
get方法
public V get(Object key) { Segment<K,V> s; // manually integrate access methods to reduce overhead HashEntry<K,V>[] tab; //获取hash值 int h = hash(key); long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE; //定位Segment if ((s = (Segment<K,V>)UNSAFE.getObjectVolatile(segments, u)) != null && (tab = s.table) != null) { //定位HashEntry for (HashEntry<K,V> e = (HashEntry<K,V>) UNSAFE.getObjectVolatile (tab, ((long)(((tab.length - 1) & h)) << TSHIFT) + TBASE); e != null; e = e.next) { K k; if ((k = e.key) == key || (e.hash == h && key.equals(k))) return e.value; } } return null; }
ConcurrentSkipListMap
相关文章推荐
- concurrent包分析-阻塞队列BlockingQueue及其实现类
- concurrent包分析-阻塞双端队列BlockingDeque及其实现类
- 四则混合运算表达式分析程序的原理及其实现
- Java对象池技术的原理及其实现 --Java对象的生命周期分析
- DEFAULT_KEYS_SHORTCUT 功能的验证 及其 源码实现分析
- 网站分析 - 吉斯特及其实现途径
- setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT) 功能的验证 及其 源码实现分析
- js实现的单机双人象棋演示及其分析
- MINA源码分析---协议解码输出接口ProtocolDecoderOutput及其实现
- Strassen矩阵算法分析及其C++实现 递归分治法(转)
- 动态星间链路分析及其STK/Matlab实现
- 一个小语言的词法分析程序原理及其实现(1)
- 【改进】BP算法及其C语言实现分析
- DEFAULT_KEYS_SHORTCUT 功能的验证 及其 源码实现分析
- QuickContact分析及其弹出窗口实现
- QuickContact分析及其弹出窗口实现
- 有趣的鼠标位置规律及其分析与实现
- Strassen矩阵算法分析及其C++实现 递归分治法(转)
- QuickContact分析及其弹出窗口实现 推荐
- 杨辉三角(Pascal Triangle)的几种C语言实现及其复杂度分析