title : 每日深耕,勤练不缀之如何保证集合是线程安全的?
java基本容器工具
前面两篇说的是Java容器类,大部分都不是线程安全的
如何保证集合是线程安全的、?
java提供了不同层面的线程安全支持。在传统集合框架内部,除了Hashtable等内容容器,还提供了所谓的同步包装器(Synchronnized Wrapper),我们可以调用Collections工具类提供的包装方法,来获取一个同步的包装容器(如 Collections.synchronizedMap),但是他们都利用的粗粒度的同步方式,在高并发情况下,性能比较低下
更加普遍的选择是利用并发包提供的线程安全容器类,
它提供了:
- 各种并发器,比如ConcurrentHashMap,CopyWriteArrayList.
- 各种线程安全队列(Queue/Deque),如ArrayBlockingQueue、SynchronousQueue
- 各种有序容器的线程安全版本
从简单的synchronized方式,到基于更加精细化的,比如基于分离锁实现的ConcurrentHashMap等并发实现
总体来说,并发包提供的容器通用场景,远远优于早期
线程安全和并发的深入考察
需要四个方面的解答
1.理解基本的线程安全工具
2.理解传统集合框架并发编程中Map存在的问题,清楚简单的同步方式的不足
3.梳理并发包内,尤其是ConcurrentHashMap采取了哪些方法来提高并发的表现
4.最好能掌握ConcurrentHashMap自身的演进
Hashtable本身比较低效,因为它的实现基本就是将put、get、size等各种方法加上"synchronized".简单来说,这就导致了所有并发程序都要争一把锁,一个线程进行同步操作时,其他职能等待,导致CPU占用100%的问题。
那我们能不能用Collections提供的同步包装器来解决问题呢?
private static class Synchronized<K,V>
implements Map<K,V>,Serializable{
private final Map<K,V> m; //Backing Map
final Object mutex; //Object on which to synchronized
//..
public int size(){
synchronized(mutex){
return m.size();