概述
Java程序员进行并发编程时,相比于其他语言的程序员而言要倍感幸福,因为并发编程大师Doug Lea不遗余力地位Java开发者提供了非常多的并发容器和框架。本章让我们一起来见识一下大师操刀编写的并发容器和框架,并通过每节的原理分析一起来学习如何设计出精妙的并发程序。
ConcurrentHashMap的实现原理与使用
ConcurrentHashMap是线程安全且高效的HashMap。下面我们一起研究一下该容器时如何在保证线程安全的同时又能保证高效的操作。
为什么要使用ConcurrentHashMap
在并发编程中使用HashMap会导致多线程间数据不可见性。而使用线程安全的HashTable效率又非常低下,基于以上两个原因,便有了ConcurrentHashMap的登场机会。
- 线程不安全的HashMap
- 效率低下的HashTable
HashTable容器使用synchronized来保证线程安全,但在线程竞争激烈的情况下HashTable的效率非常低下。因为当一个线程访问HashTable的同步方法时,其他线程也访问HashTable的同步方法,会进入阻塞或者轮询状态。如线程1使用put进行元素添加,线程2不但不能使用put方法添加元素,也不能用get方法来获取元素,所以竞争越激烈效率越低。 - ConcurrentHashMap的锁分段技术可有效提升并发访问率
HashTable容器在竞争激烈的并发环境下表现出效率低下的原因是所有访问HashTable的线程都必须竞争同一把锁,加入容器里有多把锁,每一把锁用于锁容器其中的一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效提高并发访问效率,这就是ConcurrentHashMap所使用的锁分段技术。首先将数据分成一段一段地存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一段数据的时候,其他段的数据也能被其他线程访问。