0%

ConcurrentHashMap

ConcurrentHashMap

ConcurrentHashMap使用分段锁来实现同步 (ReentrantLock实现CAS来实现的)

默认16线程
get使用volatile实现可见性不需要加锁
put使用segmentShift / segmentMask来定位segment
HashTable 则对这些方法加synchronize来实现锁,效率很低

JDK1.8进行了改进

使用链表头节点加锁,同一时间只有一个线程可以put,解决并发问题

  • 首先new一个新的hash表(nextTable)出来,大小是原来的2倍。后面的rehash都是针对这个新的hash表操作,不涉及原hash表(table)。
  • 然后会对原hash表(table)中的每个链表进行rehash,此时会尝试获取头节点的锁。这一步就保证了在rehash的过程中不能对这个链表执行put操作。
  • 通过sizeCtl控制,使扩容过程中不会new出多个新hash表来。
  • 最后,将所有键值对重新rehash到新表(nextTable)中后,用nextTable将table替换。这就避免了HashMap中get和扩容并发时,可能get到null的问题。
  • 在整个过程中,共享变量的存储和读取全部通过volatile或CAS的方式,保证了线程安全。