ConcurrentHashMap
ConcurrentHashMap中有三个层次,整个Hash表,Segment,HashEntry。
Segment数组中的每一个Segment就相当于是一个HashTable,每个HashEntry代表Hash表中的一个节点。HashEntry类如下:
除了value定义为volatile之外,其余都定义为final。
Segment继承自ReentrantLock类,所以Segment对象也能充当锁的角色。当执行put方法的时候,就可以只给对应的Segment上锁,其他Segment段依然可以并行访问。默认情况下ConcurrentHashMap会创建16个元素的Segment组,也就是说ConcurrentHashMap默认支持16个线程的并发。
ConcurrentHashmap的get操作比较简单,先通过一次hash定位到segment的位置,然后再通过一次hash定位到具体的元素。get操作不用加锁,除非读到空值则需要加锁重读。因为get方法里将要使用的共享变量都定义为了volatile,这样就会保证读到的一定是最新的值,不会读到过期的值。根据Java内存模型的happens-before原则,volatile变量的写入操作发生在读取操作之前,因此,就算是有多个线程读写volatile变量,get操作拿到的也是最新的值,这是用volatile替换锁的经典应用场景。