JDK1.7,采用分段锁技术

本质上还是采用数组+链表的形式存储键值对的。为了提高并发,把原来的整个 table 划分为 n 个 Segment 。从整体来看,它是一个由 Segment
组成的数组。每个 Segment 里边是由 HashEntry 组成的数组,每个 HashEntry之间又可以形成链表。我们可以把每个 Segment
看成是一个小的 HashMap,其内部结构和 HashMap 是一模一样的。当对某个 Segment 加锁时,不会影响到其他 Segment
的读写,降低锁的竞争。

JDK1.8,采用的是Synchronized + CAS + volatile

Synchronized 由于锁优化和锁升级性能得到了很大提升,通过 CAS 乐观锁实现原子操作,利用volatile保证可见性。

下面时JDK1.8ConcurrentHashMap源码的简单解析:

volatile大量使用
static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K
key; volatile V val; volatile Node<K,V> next; } static final class
TreeBin<K,V> extends Node<K,V> { TreeNode<K,V> root; volatile TreeNode<K,V>
first; volatile Thread waiter; volatile int lockState; } transient volatile
Node<K,V>[] table; private transient volatile Node<K,V>[] nextTable; private
transient volatile long baseCount; private transient volatile int sizeCtl;
private transient volatile int transferIndex; private transient volatile int
cellsBusy; private transient volatile CounterCell[] counterCells;
put()
public V put(K key, V value) { return putVal(key, value, false); } 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) { // 通过 CAS
原子操作,把新节点插入到此位置,这保证了只有一个线程可以 CAS 成功,其它线程都会失败。 if (casTabAt(tab, i, null, new
Node<K,V>(hash, key, value, null))) break; // no lock when adding to empty bin
} else if ((fh = f.hash) == MOVED) tab = helpTransfer(tab, f); else { V oldVal
= null; // 使用同步锁的方式,来保证线程安全,给头节点加锁 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; } } } // 给元素个数加1,有可能会触发扩容 addCount(1L, binCount); return null; }
 

技术
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:766591547
关注微信