ConcurrentHashMap

Catalogue   

ConcurrentHashMap 是一个并发散列映射表的实现,它允许完全并发的读取,并且支持给定数量的并发更新。
相比于 HashTable 和用同步包装器包装的HashMap(Collections.synchronizedMap(new HashMap())),ConcurrentHashMap 拥有更高的并发性。
在 HashTable 和由同步包装器包装的 HashMap 中,使用一个全局的锁来同步不同线程间的并发访问。同一时间点,只能有一个线程持有锁,
也就是说在同一时间点,只能有一个线程能访问容器。这虽然保证多线程间的安全并发访问,但同时也导致对容器的访问变成串行化的了。
在使用锁来协调多线程间并发访问的模式下,减小对锁的竞争可以有效提高并发性。有两种方式可以减小对锁的竞争: 减小请求同一个锁的频率。
减少持有锁的时间。 ConcurrentHashMap 的高并发性主要来自于三个方面:

  1. 用分离锁实现多个线程间的更深层次的共享访问。
  2. 用HashEntery对象的不变性来降低执行读操作的线程在遍历链表期间对加锁的求。
  3. 通过对同一个 volatile 变量的写 / 读访问,协调不同线程间读 / 写操作的内存可见性。 使用分离锁,减小了请求同一个锁的频率。

通过 HashEntery 对象的不变性及对同一个 volatile 变量的 读 / 写来协调内存可见性,使得读操作大多数时候不需要加锁就能成功获取到需要的值。
由于散列映射表在实际应用中大多数操作都是成功的读操作,所以 2 和 3 既可以减少请求同一个锁的频率,也可以有效减少持有锁的时间。
通过减小请求同一个锁的频率和尽量减少持有锁的时间,使得 ConcurrentHashMap 的并发性相对于 HashTable 和用同步包装器包装的 HashMap有了质的提高。