首页  

java8 ConcurrentHashMap 锁机制     所属分类 java8 浏览量 1148
jdk7 使用分段锁  ReentrantLock
jdk8 放弃分段锁  首结点 cas , 其他节点 使用 首节点锁 synchronized

jdk7 
数组加链表
Segment(段)   class Segment  extends ReentrantLock 
initialCapacity 初始总容量,默认16
loadFactor 加载因子,默认0.75
concurrencyLevel 并发级别,默认16

并发级别控制Segment个数,创建后Segment的个数不能变,扩容过程过改变的是每个Segment的大小。

关于分段锁
Segment继承ReentrantLock
分段锁 提升并发性 
缺点
浪费内存空间(不连续,碎片化)
当某个段很大时,性能下降


jdk8 
数组+链表+红黑树
数组可以扩容,链表可以转化为红黑树。

扩容机制
当前容量超过阈值
当链表中元素个数超过默认设定(8个),当数组的大小未超过64,此时进行数组扩容,如果超过则将链表转化成红黑树
当数组大小已经超过64并且链表中的元素个数超过默认设定(8个)时,将链表转化为红黑树


final V putVal(K key, V value, boolean onlyIfAbsent) { if (key == null || value == null) throw new NullPointerException(); int hash = spread(key.hashCode()); int binCount = 0; for (Node<K,V>[] tab = table;;) { Node<K,V> f; int n, i, fh; if (tab == null || (n = tab.length) == 0) tab = initTable(); else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) { if (casTabAt(tab, i, null, new Node<K,V>(hash, key, value, null))) break; // no lock when adding to empty bin // 首节点cas } else if ((fh = f.hash) == MOVED) tab = helpTransfer(tab, f); else { V oldVal = null; // 其他节点 使用 synchronized synchronized (f) { if (tabAt(tab, i) == f) { if (fh >= 0) { binCount = 1; for (Node<K,V> e = f;; ++binCount) { K ek; if (e.hash == hash && ((ek = e.key) == key || (ek != null && key.equals(ek)))) { oldVal = e.val; if (!onlyIfAbsent) e.val = value; break; } Node<K,V> pred = e; if ((e = e.next) == null) { pred.next = new Node<K,V>(hash, key, value, null); break; } } } else if (f instanceof TreeBin) { Node<K,V> p; binCount = 2; if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key, value)) != null) { oldVal = p.val; if (!onlyIfAbsent) p.val = value; } } } } if (binCount != 0) { if (binCount >= TREEIFY_THRESHOLD) treeifyBin(tab, i); if (oldVal != null) return oldVal; break; } } } addCount(1L, binCount); return null; }
ConcurrentHashMap在jdk7和8中的区别 HashMap和ConcurrentHashMap中的hash函数 ConcurrentHashMap读不需要加锁的秘密 ConcurrentHashMap size 实现要点 ConcurrentHashMap读操作为什么不需要加锁

上一篇     下一篇
redis优化要点

devops简介及工具链

jenkins简介

两个线程,一个输出字母,一个输出数字,交替输出1A2B3C4D5E6F

java面试题合集

单例模式几种实现方式