HashMap和HashTable还有ConcurrentHashMap的区别

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37465188/article/details/85340949

HashMap

简单的叙述HashMap 1.7 -> 1.8 的区别
JDK 1.7的扩容

效率低下的HashTable

HashTable容器使用synchronized来保证线程安全,但在线程竞争激烈的情况下,HashTable的效率非常低下。因为当一个线程访问HashTable的同步方法时,其他线程访问HashTable的同步方法时,可能会进入阻塞或轮询状态。如线程1使用put进行添加元素,线程2不但不能使用put方法添加元素,并且也不能使用get方法来获取元素,所以竞争越激烈效率越低。

ConcurrentHashMap

主要设计上的变化有以下几点:

  • 不采用segment而采用node,锁住node来实现减小锁粒度。
  • 设计了MOVED状态 当resize的中过程中 线程2还在put数据,线程2会帮助resize。
  • 使用3个CAS操作来确保node的一些操作的原子性,这种方式代替了锁。
  • sizeCtl的不同值来代表不同含义,起到了控制的作用。
  • 至于为什么JDK8中使用synchronized而不是ReentrantLock,我猜是因为JDK8中对synchronized有了足够的优化吧。
  • ForwardingNode一个特殊的Node节点,hash值为-1(MOVED常量),其中存储nextTable的引用。只有table发生扩容的时候,ForwardingNode才会发挥作用,作为一个占位符放在table中表示当前节点为null或则已经被移动
  • 扩容时,如果另外一个线程get()时,发现自己get的节点是ForwardingNode,它会立马转头去帮助扩容。

参考资料:
ConcurrentHashmap的1.7 与 1.8浅谈

猜你喜欢

转载自blog.csdn.net/qq_37465188/article/details/85340949