ConcurrentHashMap

Posted 一梦三十载

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ConcurrentHashMap相关的知识,希望对你有一定的参考价值。

ConcurrentHashMap中的key和value值都不能为null,HashMap中key可以为null,HashTable中key不能为null。
并发编程中ConcurrentHashMap是一个常用的数据结构,在线程安全的基础上提供了更好的写并发能力,是线程安全的类并不能保证使用了ConcurrentHashMap的操作都是线程安全的,大量的利用了volatile,final,CAS等lock-free技术来减少锁竞争对于性能的影响
使用分段锁技术,将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,
其他段的数据也能被其他线程访问,每个Segment段(继承ReentrantLock),能够实现真正的并发访问

ConcurrentHashMap中主要实体类就是三个:ConcurrentHashMap(整个Hash表),Segment(桶),HashEntry(节点)


put方法的线程会获得锁,只有当此线程的put方法执行结束后才会释放锁,获得锁的线程会通知其他试图操作put方法的线程,并通知其他线程出于等待状态,直到释放锁后,其他线程才会去重新竞争锁。保证了ConcurrentHashMap的线程安全

get方法无需加锁,由于其中涉及到的共享变量都使用volatile修饰,volatile可以保证内存可见性,所以不会读取到过期数据。ConcurrentHashMap实现技术是保证HashEntry几乎是不可变的。HashEntry代表每个hash链中的一个节点,其结构如下所示:

static final class HashEntry<K,V> {

         final K key;  final int hash;   

         volatile V value;  volatile HashEntry<K,V> next;

}

总结:
ConcurrentHashMap使用了线程锁分段技术,每次访问只允许一个线程修改哈希表的映射关系,所以是线程安全的

ConcurrentHashMap采用了非常精妙的"分段锁"策略,ConcurrentHashMap的主干是个Segment数组Segment继承了ReentrantLock,所以它就是一种可重入锁(ReentrantLock)。在ConcurrentHashMap,一个Segment就是一个子哈希表,Segment里维护了一个HashEntry数组,并发环境下,对于不同Segment的数据进行操作是不用考虑锁竞争的。(理论上就允许16个线程并发执行) 

Segment类似于HashMap,一个Segment维护着一个HashEntry数组
如果用户不指定则会使用默认值,initialCapacity为16,loadFactor为0.75(负载因子,扩容时需要参考),concurrentLevel为
16

 

可以使用CocurrentHashMap来代替Hashtable吗?
这是一个很热门的面试题,因为ConcurrentHashMap越来越多人用了。Hashtable是synchronized的,但是ConcurrentHashMap同步性能更好,因为它仅仅根据同步级别对map的一部分进行上锁。ConcurrentHashMap当然可以代替HashTable,但是HashTable提供更强的线程安全性

以上是关于ConcurrentHashMap的主要内容,如果未能解决你的问题,请参考以下文章