ConcurrentHashMap

来源:互联网 发布:形容网络与生活的词语 编辑:程序博客网 时间:2024/06/17 15:29

1、HashMapHashtableConcurrentHashMap 的原理和区别?

(1)HashMap线程不安全的,《Java并发编程的艺术》中说道HashMap 在并发执行 put 操作时会引起死循环,导致 CPU 利用率接近100%。因为多线程会导致 HashMap 的 Node 链表形成环形数据结构,一旦形成环形数据结构,Node 的 next 节点永远不为空,就会在获取 Node 时产生死循环(其实死循环是在扩容时而不是发生在put操作时),HashMap 在并发时可能出现的问题主要是两方面,首先如果多个线程同时使用put方法添加元素,而且假设正好存在两个 put 的 key 发生了碰撞(根据 hash 值计算的 bucket 一样),那么根据 HashMap 的实现,这两个 key 会添加到数组的同一个位置,这样最终就会发生其中一个线程的 put 的数据被覆盖。第二就是如果多个线程同时检测到元素个数超过数组大小* loadFactor ,这样就会发生多个线程同时对 Node 数组进行扩容,都在重新计算元素位置以及复制数据,但是最终只有一个线程扩容后的数组会赋给 table,也就是说其他线程的都会丢失,并且各自线程 put 的数据也丢失;(2)Hashtable 线程安全,但当一个线程访问 Hashtable 的同步方法时,其他线程如果也要访问同步方法,会被阻塞住。举个例子,当一个线程使用 put 方法时,另一个线程不但不可以使用 put 方法,连 get 方法都不可以。所以效率低,因为是 Hashtable 是使用 synchronized 的,所有线程竞争同一把锁;(3)而ConcurrentHashMap 不仅线程安全而且效率高,使用了锁分离技术允许多个修改操作并发进行。它使用了多个锁来控制对hash表的不同部分进行的修改。ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的Hashtable,它们有自己的锁。只要多个修改操作发生在不同的段上,它们就可以并发进行

注:并发编程实践中,ConcurrentHashMap是一个经常被使用的数据结构,相比于Hashtable以及Collections.synchronizedMap(),ConcurrentHashMap在线程安全的基础上提供了更好的写并发能力,但同时降低了对读一致性的要求。ConcurrentHashMap的设计与实现非常精巧,大量的利用了volatile,final,CAS等lock-free技术来减少锁竞争对于性能的影响。

2、ConcurrentHashMap的锁分段技术。

ConcurrentHashMap所使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问,能够实现真正的并发访问。假如容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率。

3.ConcurrentHashMap的读是否要加锁,为什么。

ConcurrentHashMap完全允许多个读操作并发进行,读操作并不需要加锁(get 无需加锁,只是读取并不会对数据发生改变;readValueUnderLock 正常情况不会被执行;e.value 不会为 null?有待查证http://blog.csdn.net/enjoyinwind/article/details/41148895)。 书上的解释是: 因为count和e.value都是volatile的, 所以读写具有原子性,并且根据happen-before原则, 读,写同时发生时, 写先于读发生。

4、ConcurrentHashMap的迭代器是强一致性的迭代器还是弱一致性的迭代器?

concurrenthashmap是弱一致的,iterator 都是弱一致性的在这种迭代方式中,当iterator被创建后集合再发生改变就不再是抛出ConcurrentModificationException,取而代之的是在改变时new新的数据从而不影响原有的数据,iterator完成后再将头指针替换为新的数据,这样iterator线程可以使用原来老的数据,而写线程也可以并发的完成改变,更重要的,这保证了多个线程并发执行的连续性和扩展性,是性能提升的关键。

PS:

Vector 是强一致性,只保证add,remove操作是线程安全的,remove完所有元素以后是不会自己阻塞的。

ArrayBlockingQueue 弱一致,add到确定大小或remove完所有元素是会自己阻塞的。

ConcurrentHashMap的get,hash table的迭代器是强一致性的,但并不能完全被取代。

原创粉丝点击