文章目录
写在前面
之间一直对ConcurrentHashMap理解不深,感觉就是HashMap+Segment一个锁就好了
经过一些事情后感觉自己还是缺钱的很多.故开始慢慢学习源码.
ConcurrentHashMap源码很长,我自己总结的
之前看的都是jdk1.7的.现在看jdk1.8中的源码.
jdk1.8中,在ConcurrentHashMap是由 哈希表
+ 链表
+ 红黑树
组成的.
ConcurrentHashMap常量
打开源码,首先我们可以看到很多常量,和HashMap类似
主要的常量有:
MAXIMUM_CAPACITY
最大容量
private static final int MAXIMUM_CAPACITY = 1 << 30;
DEFAULT_CAPACITY
默认容量 16
private static final int DEFAULT_CAPACITY = 16;
DEFAULT_CONCURRENCY_LEVEL
最大并发容量,默认为16, jdk1.8中没有用到
LOAD_FACTOR
负载因子,默认为0.75,
private static final float LOAD_FACTOR = 0.75f;
TREEIFY_THRESHOLD
当一个链表大于8时,这个链表将变成一个红黑树
static final int TREEIFY_THRESHOLD = 8;
UNTREEIFY_THRESHOLD
我们知道到链表大于8时候,会变成一个红黑树.
但是可能有很多remove操作,当这个红黑树节点数小于6时候,变成链表
static final int UNTREEIFY_THRESHOLD = 6;
声明的状态
static final int MOVED = -1; // hash for forwarding nodes
static final int TREEBIN = -2; // hash for roots of trees
static final int RESERVED = -3; // hash for transient reservations
HASH_BITS
计算哈希值时需要和 Hash_bits相与,这个值默认为全1
位运算一下将负数转化为正数
static final int HASH_BITS = 0x7fffffff; // usable bits of normal node hash
MAX_RESIZERS
接下来的三个参数还没看到,之后填坑
private static final int MAX_RESIZERS = (1 << (32 - RESIZE_STAMP_BITS)) - 1;
RESIZE_STAMP_BITS
private static int RESIZE_STAMP_BITS = 16;
RESIZE_STAMP_SHIFT
private static final int RESIZE_STAMP_SHIFT = 32 - RESIZE_STAMP_BITS;
NCPU
获取CPU的个数
static final int NCPU = Runtime.getRuntime().availableProcessors();
Node内部类
我们都知道HashMap是以Key和Value定义的,所以ConcurrentHashMap定义了内部类来存放Key和Value
从代码中可以看到,是实现了一个链表的操作
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
volatile V val;
volatile Node<K,V> next;
Node(int hash, K key, V val, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.val = val;
this.next = next;
}
public final K getKey() {
return key; }
public final V getValue() {
return val; }
public final int hashCode() {
return key.hashCode() ^ val.hashCode(); }
public final String toString(){
return key + "=" + val; }
public final V setValue(V value) {
// 如果SetValue ,这直接抛出异常
throw new UnsupportedOperationException();
}
public final boolean equals(Object o) {
Object k, v, u; Map.Entry<?,?> e;
return ((o instanceof Map.Entry) &&
(k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
(v = e.getValue()) != null &&
(k == key || k.equals(key)) &&
(v ==