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依次进行加锁,获取返回值后再依次解锁。

 

  

 

posted @ 2018-01-16 12:46  七分饱  阅读(157)  评论(0编辑  收藏  举报