JAVA程序员

Queue

2017-08-24  本文已影响41人  刺風
一、Queue是啥?
  1. Queue是个接口。
  2. Queue接口与List、Set同一级别,都是继承了Collection接口。
  3. Queue接口用以支持队列的常见操作。
二、队列是啥?

队列是一种常用的数据存储方式,表现形式为先进先出,可以想象成是一个有序的管道,往里放数据时,先进入管道的肯定先出来,在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列。

三、阻塞队列

阻塞队列 (BlockingQueue)是java.util.concurrent包下重要的数据结构,BlockingQueue提供了线程安全的队列访问方式:当阻塞队列进行插入数据时,如果队列已满,线程将会阻塞等待直到队列非满;从阻塞队列取数据时,如果队列已空,线程将会阻塞等待直到队列非空。并发包下很多高级同步类的实现都是基于BlockingQueue实现的。
BlockingQueue 是个接口,java.util.concurrent包下提供以下 BlockingQueue 接口的实现类:
1.ArrayDeque:数组双端队列。
2.PriorityQueue:优先级队列。
3.ConcurrentLinkedQueue:基于链表的并发队列。
4.DelayQueue:延期阻塞队列 。
5.ArrayBlockingQueue:基于数组的并发阻塞队列。
6.LinkedBlockingQueue:基于链表的FIFO阻塞队列。
7.LinkedBlockingDeque:基于链表的FIFO双端阻塞队列。
8.PriorityBlockingQueue:带优先级的无界阻塞队列。
9.SynchronousQueue:并发同步阻塞队列。

小结:阻塞队列(Blocking queue)提供了可阻塞的put和take方法,它们与可定时的offer和poll是等价的。如果Queue已经满了,put方法会被阻塞直到有空间可用;如果Queue是空的,那么take方法会被阻塞,直到有元素可用。Queue的长度可以有限,也可以无限;无限的Queue永远不会充满,所以它的put方法永远不会阻塞。

四、非阻塞队列

基于链接节点的、无界的、线程安全。此队列按照 FIFO(先进先出)原则对元素进行排序。队列的头部 是队列中时间最长的元素。队列的尾部 是队列中时间最短的元素。新的元素插入到队列的尾部,队列检索操作从队列头部获得元素。当许多线程共享访问一个公共 collection 时,ConcurrentLinkedQueue 是一个恰当的选择。此队列不允许 null 元素。

五、结论

在并发编程中,一般推荐使用阻塞队列,这样实现可以尽量地避免程序出现意外的错误。阻塞队列使用最经典的场景就是socket客户端数据的读取和解析,读取数据的线程不断将数据放入队列,然后解析线程不断从队列取数据解析。还有其他类似的场景,只要符合生产者-消费者模型的都可以使用阻塞队列。
使用非阻塞队列,虽然能即时返回结果(消费结果),但必须自行编码解决返回为空的情况处理(以及消费重试等问题)。

上一篇下一篇

猜你喜欢

热点阅读