ConcurrentHashMap读操作为什么不需要加锁
所属分类 java
浏览量 1478
java8
public V get(Object key) {
Node[] tab; Node e, p; int n, eh; K ek;
// h>=0
int h = spread(key.hashCode());
if ((tab = table) != null && (n = tab.length) > 0 &&
(e = tabAt(tab, (n - 1) & h)) != null) {
//读取首节点的Node元素
if ((eh = e.hash) == h) {
//如果该节点就是首节点就返回
if ((ek = e.key) == key || (ek != null && key.equals(ek)))
return e.val;
}
// hash值具体含义
//eh=-1,说明该节点是一个ForwardingNode,正在迁移,调用ForwardingNode的find方法去nextTable里找
//eh=-2,说明该节点是一个TreeBin,调用TreeBin的find方法遍历红黑树
//eh>=0,说明该节点下挂的是一个链表,直接遍历该链表即可
// ForwardingNode 和 TreeBin 都可以调用 find 方法
else if (eh < 0)
return (p = e.find(h, key)) != null ? p.val : null;
while ((e = e.next) != null) {
// 链表 直接遍历
if (e.hash == h &&
((ek = e.key) == key || (ek != null && key.equals(ek))))
return e.val;
}
}
return null;
}
桶定位 tabAt 和 Node 定义
/**
* The array of bins. Lazily initialized upon first insertion.
* Size is always a power of two. Accessed directly by iterators.
*/
transient volatile Node[] table;
/**
* The next table to use; non-null only while resizing.
*/
private transient volatile Node[] nextTable;
static final Node tabAt(Node[] tab, int i) {
return (Node)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);
}
static class Node implements Map.Entry {
final int hash;
final K key;
volatile V val;
volatile Node next;
Unsafe getObjectVolatile
hash 和 key 不可变 ,final 保证可见性
val 和 next volatile 保证可见性
table数组 volatile 保证引用可见性
volatile + final 保证可见性
上一篇
下一篇
分布式限流方案
lua函数使用说明
jvm相关知识点
java里的协程
一致性算法raft要点
消息队列知识点