Java并发集合类

时间:2021-10-31 18:18:04

        在Java类库中出现的第一个关联的集合类是 HashtableHashtable 提供了一种易于使用的、线程安全的、关联的map功能。然而,线程安全性付出代价是――Hashtable 的所有方法都是同步的。Hashtable 的后继者HashMap 是作为JDK1.2中的集合框架的一部分出现的,它通过提供一个不同步的基类和一个同步的包装器Collections.synchronizedMap ,解决了线程安全性问题。通过将基本的功能从线程安全性中分离开来,Collections.synchronizedMap 允许需要同步的用户可以拥有同步,而不需要同步的用户则不必为同步付出代价。

        同步的集合包装器 synchronizedMapsynchronizedList ,有时也被称作 有条件地线程安全――所有单个的操作都是线程安全的,但是多个操作组成的操作序列却可能导致数据争用,因为在操作序列中控制流取决于前面操作的结果。例如对于这样的功能put-if-absent语句块――如果一个条目不在Map 中,那么添加这个条目。该功能通过containsKey() 方法和 put() 方法组合起来。要保证原子性操作,就需要对该语句块加上同步锁。

        Queue接口

java.util 包为集合提供了一个新的基本接口:java.util.Queue,是一个先入先出(FIFO)的数据结构。

        PriorityQueue类

        BlockingQueue接口

        阻塞队列,它实质上就是一种带有一点扭曲的 FIFO 数据结构。它提供了可阻塞的put和take方法。如果Queue已经满了,put方法会被阻塞直到有空间可用;如果Queue是空的,那么take方法会被阻塞,直到有元素可用。Queue的长度可用有限,也可以无限;无限的Queue永远不会充满,所以它的put方法永远不会被阻塞。阻塞队列支持生产者-消费者设计模式。BlockingQueue可以使用任意数量的生产者和消费者,从而简化了生产者-消费者设计的实现。

BlockingQueue接口的几个主要的实现类:

  • ArrayBlockingQueue :一个由数组支持的有界队列。
  • LinkedBlockingQueue :一个由链接节点支持的可选有界队列。
  • PriorityBlockingQueue :一个由优先级堆支持的*优先级队列。
  • DelayQueue :一个由优先级堆支持的、基于时间的调度队列。
  • SynchronousQueue :一个利用 BlockingQueue 接口的简单聚集(rendezvous)机制。

        PriorityBlockingQueue 是具有*限容量的队列,它利用所包含元素的 Comparable 排序顺序来以逻辑顺序维护元素。可以将它看作TreeSet 的可能替代物。对于没有天然顺序的元素,可以为构造函数提供一个Comparator 。不过对PriorityBlockingQueue,有一个要特别注意的地方:iterator() 返回的 Iterator 实例,元素是不具有优先级顺序的。如果必须以优先级顺序遍历所有元素,那么让它们都通过toArray() 方法并自己对它们排序,像Arrays.sort(pq.toArray())

        SynChronousQueue,它根本上不是一个真正的队列,因为它不会为队列元素维护任何存储空间。不过,它维护一个排队的线程清单,这些线程等待把元素加入队列或移出队列。它非常直接的移交工作,减少了生产者和消费者之间移动数据的延迟时间。直接移交同样会给生产者带来更多关于任务状态的反馈信息:当移交被接受,它就知道消费者已经得到了任务。 因为SynchronousQueue没有存储的能力,所以除非另一个线程已经准备好参与移交工作,否则put和take会一直阻塞。比较适合于消费者充足的情况。

     

            CopyOnWriteArrayList 和 CopyOnWriteArraySet ,最适合于读操作通常大大超过写操作的情况。