我们常用到的一些集合对象像ArrayList、LinkedList、HashSet、TreeSet、PriorityQueue等都不是线程安全的,java Concurrent包提供了一些并发集合对象。
1. Concurrent Queues:
ConcurrentLinkedQueue,并发队列的链表实现,它实现了Queue本身具备的基本操作。它的并发控制是通过原子操作对象AtomicReferenceFieldUpdater来完成的,这个类的原子操作是由底层处理器来实现的,参看另一篇java并发(atomic操作)的文章。
BlockingQueue,阻塞队列,它为Queue提供两种额外的操作:获取元素时等待队列不为空,以及存贮元素是等待空间变得可用。等待的时间可以是无限制或等待某一指定时间,以存贮元素为例,put(e)方法将会无限阻塞直至操作成功,而offer(e,time,unit)是在达到特定阻塞时间放弃操作。
它的直接实现子类包括:ArrayBlockingQueue,阻塞队列的数组实现方式。异步访问通过ReetrantLock控制,而阻塞操作由Concurrent包中的Condition类完成,其中的await()方法执行无限制阻塞,而awaitNanos(time)会等待相应的时间后会继续执行。程序运行到指定的await方法时,当前线程的锁会自动被释放并等待唤醒,具体唤醒条件1)等待时间到,2)其他线程调用Condition的signal()方法,3)其他线程调用Condition的signalAll()方法,4)其他线程interrupt()该线程。
LinkedBlockingQueue, BlockingQueue的链表实现方式。它的同步控制和阻塞操的实现方式和ArrayBlockingQueue类似。
还有其他的一些Queue对象,像DelayQueue、SynchronousQueue等就不做详细介绍。
2. Concurrent List:
CopyOnWriteArrayList,是一个在语义上提供写时复制一份副本的List,对这个集合的每次修改都要对当前数据结构新建一个副本,相对来说写的花销是挺大的。它的并发控制由ReentrantLock完成,而它的复制操作由Arrays.copyof()方法完成。
3. Concurrent Set:
CopyOnWriteArraySet,一个内部基于CopyOnWriteArrayList实现的Set集合。
4. Concurrent Map:
Map并不是一个集合对象,但也属于集合框架家族的成员,这里也一起描述。它的对象有ConcurrentHashMap,是一个并发的HashMap。在ConcurrentHashMap 中引入了一个Segment对象,每个Segment 又是一个hash 表,ConcurrentHashMap 相当于是两级Hash 表,然后锁是在Segment 一级进行的,提高了并发性(Segment直接继承了ReentrantLock对象以控制异步访问)。
ConcurrentSkipListMap,是基于跳跃链表实现的一个Map,与TreeMap相似,且具有相当的排序功能。它的异步控制通过原子操作对象AtomicReferenceFieldUpdater完成。