java基础,集合,ConcurrentHashMap,JDK1.7理解
- 线程安全的map集合
- 内部类:
1 static final class HashEntry<K,V> { 2 final int hash; 3 final K key; 4 volatile V value; 5 volatile HashEntry<K,V> next;
HashEntry中的value以及next都被volatile修饰,这样在多线程读写过程中能够保持它们的可见性,
有next就实现链表
- 使用到分段锁,segment,put数据的时候,会进行两次hash,先是trylock 视情况 lock
不能存入null值
先对key进行判断,看在哪一个分段,(分段是否初始化,默认ConcurrentHashMap只初始化第一段,没有就初始化分段),
保证每个数据均匀分散到16个分段中,所以使用两次hash
put的时候,是线程安全的
- 在get取值,containkey的(ConcurrentHashMap在弱一致性上的体现,)
没有使用锁,而是通过Unsafe对象的getObjectVolatile()方法提供的原子读语义,来获得Segment以及对应的链表,然后对链表遍历判断是否存在key相同的节点以及获得该节点的value。
但由于遍历过程中其他线程可能对链表结构做了调整,因此get和containsKey返回的可能是过时的数据,这一点是ConcurrentHashMap在弱一致性上的体现
hashtable是强一致性,hashtable在取值的时候也是线程安全放入
- 对于整个ConcurrentHashMap的操作 size,containvalue
首先不加锁循环执行以下操作:循环所有的Segment(通过Unsafe的getObjectVolatile()以保证原子读语义),获得对应的值以及所有Segment的modcount之和。
如果连续两次所有Segment的modcount和相等,则过程中没有发生其他线程修改ConcurrentHashMap的情况,返回获得的值。
当循环次数超过预定义的值时,这时需要对所有的Segment依次进行加锁,获取返回值后再依次解锁。