并发容器
java5.0提供了多种并发容器,把所有对容器的访问都串行化,以实现他们的线程安全性,代价是严重降低并发性,当多个线程对其进行访问时,吞吐量将严重降低
Java5.0中增加了ConcurrentHashMap用于替代同步且基于散列的Map,以及CopyOnWriteArrayList,用于遍历操作为主要操作的情况下代替同步的List。
并且新增了两种容器类型,Queue和BlockingQueue,Queue用来临时保存一组等待处理的元素,有几种实现,包括:ConcurrentLinkedQueue 传统的先进先出队列,以及PriorityQueue,这是一个非并发的优先队列,Priority是优先级的意思嘛。而BlockingQueue是Queue的扩展,增加了可阻塞的插入和获取操作,如果队列为空那么获取的操作将一直等待下去。如果已满则插入的操作将等待下去。
ConcurrentHashMap
它用一个完全不同的策略来提供更高的并发性和伸缩性,并不是原来的在每个方法上都在同一个锁上同步并使得每次只有一个线程可以访问容器,而是使用一种叫做分段锁的技术。(我猜想应该是对个方法之间有密切联系的加上不同的锁,所以这个类里应该是有几个锁同时存在,包括读锁和写锁)。它的改进还有不会再抛出ConcurrentModificationException了。因此不需要在迭代过程中对容器进行加锁。但是也有它的缺点,比如Size和isempty这两个方法 不能准确的获取数值了,size只是一个估计值,isempty的结果已经不太可用了 。它们的性能弱化是为了换取更常用操作的性能优化,比如get put containkey 和remove等
与hashtable、synchronizedMap相比,ConcurrentHashMap有更多的优势 更少的劣势,因此可以做为替代同步Map的类,有一种情况才放弃使用它,只有当程序需要加锁Map以进行独占访问时。
额外的原子操作
ConcurrentHashMap不能被加锁实现独占访问,所以我们不能通过客户端加锁建立新的原子操作。但是一些常见的复合操作。比如若没有则添加,若相等则移除已经实现为原子操作并且在ConcurrentHashMap上声明了,如果你需要在现有的同步Map中添加这样的功能,那么你应该考虑用ConcurrentHashMap了。
CopyOnWriteArrayList
和ConcurrentHashMap一样,它是同步List的替代类。还有CopyOnWriteSet也是。它们都不需要在迭代过程中对容器进行加锁,不会再抛出ConcurrentModificationException了。它们的名字的意思 是写入时复制。每当修改容器时都会复制低层数组。都会创建并重新发布一个新的容器副本 。它会保留一个指向底层基础数组的引用,这个数组当前位于 迭代器的起始位置,由于它不会被修改,所以只需确保数组内容的可见性。仅当迭代操作远远多于修改操作时才应该使用写入时复制容器。
下一节内容应该讲同步工具和队列知识,但是之前已经学过了