JDK 1.5 之前
Vector、Hashtable
旧版本的集合主要有两个 Vector 和 Hashtable,在 java.util包下。
这两个类保证线程安全都是采用 synchronized修饰方法的方式。在1.5之前,效率不高,现在已基本弃用。
JDK 1.5 之后
jdk1.5之后,在 java.util.concurrent包下,新加入了几个高效的线程安全集合类。
常见的有:CopyOnWriteArrayList、CopyOnWriteArraySet、ConcurrentLinkedQueue、BlockingQueue、ConcurrentHashMap。
CopyOnWriteArrayList
线程安全的ArrayList,加强版的读写分离。
写加锁,读无锁,读写不阻塞,优于读写锁。
线程安全实现方式:写入时,先copy一个容器副本,再添加新元素,最后替换引用。是一种用空间换取线程安全的实现方式。
使用方式和一般的ArrayList一样。
CopyOnWriteArraySet
线程安全的set集合,底层是一个 CopyOnWriteArrayList。
与 CopyOnWriteArrayList 的不同是添加元素的 add() 方法使用的 CopyOnWriteArrayList 的 addIfAbsent() 方法实现。会遍历整个数组。如果元素已存在,则不添加,丢弃副本。
ConcurrentLinkedQueue
无界队列,元素个数无上限,可以一直添加。
没有使用锁的方式(无锁),而是采用CAS算法(Compare And Switch ——比较交换算法)实现线程安全。
BlockingQueue
生产者消费者模式的最好实现。
其重要的两个实现类为:
ArrayBlockingQueue:数组实现,需要自定义元素上限。
LinkedBlockingQueue:链表实现,默认元素上限为 Integer.MAX_VALUE。
ConcurrentHashMap
jdk1.8之前:
采用分段锁设计的线程安全Map集合,初始容量默认为16段(Segment)。
不是对整个map加锁,而是对每个segment加锁,以提高效率。最理想的状态是16个对象分别存入16个segment,并发量为16。
jdk1.8开始:
采用CAS算法实现同步。
使用方式与HashMap无异。