详解Java阻塞队列(BlockingQueue)的实现原理

  

阻塞队列util . concurrent (BlockingQueue)是Java包下重要的数据结构,BlockingQueue提供了线程安全的队列访问方式:当阻塞队列进行插入数据时,如果队列已满,线程将会阻塞等待直到队列非满;从阻塞队列取数据时,如果队列已空,线程将会阻塞等待直到队列非空。并发包下很多高级同步类的实现都是基于BlockingQueue实现的。

  

<强> BlockingQueue的操作方法

  

BlockingQueue具有4组不同的方法用于插入,移除以及对队列中的元素进行检查。如果请求的操作不能得到立即执行的话,每个方法的表现也不同。这些方法如下:
  

  

详解Java阻塞队列(BlockingQueue)的实现原理

  

<强>四组不同的行为方式解释:

  
      <李>抛异常:如果试图的操作无法立即执行,抛一个异常。   <李>特定值:如果试图的操作无法立即执行,返回一个特定的值(常常是真/假)。   <李>阻塞:如果试图的操作无法立即执行,该方法调用将会发生阻塞,直到能够执行。   <李>超时:如果试图的操作无法立即执行,该方法调用将会发生阻塞,直到能够执行,但等待时间不会超过给定值。返回一个特定值以告知该操作是否成功(典型的是真/假)。   
  

无法向一个BlockingQueue中插入空。如果你试图插入空,BlockingQueue将会抛出一个NullPointerException。

  

可以访问到BlockingQueue中的所有元素,而不仅仅是开始和结束的元素,比如说,你将一个对象放入队列之中以等待处理,但你的应用想要将其取消掉。那么你可以调用诸如删除(o)方法来将队列之中的特定对象进行移除。但是这么干效率并不高(译者注:基于队列的数据结构,获取除开始或结束位置的其他对象的效率不会太高),因此你尽量不要用这一类的方法,除非你确实不得不那么做。

  

<强> BlockingQueue的实现类

  

BlockingQueue是个接口,你需要使用它的实现之一来使用BlockingQueue, Java.util。concurrent包下具有以下BlockingQueue接口的实现类:
  

  
      <李> <>强ArrayBlockingQueue: 之间是一个有界的阻塞队列,其内部实现是将对象放到一个数组里。有界也就意味着,它不能够存储无限多数量的元素。它有一个同一时间能够存储元素数量的上限。你可以在对其初始化的时候设定这个上限,但之后就无法对这个上限进行修改了(译者注:因为它是基于数组实现的,也就具有数组的特性:一旦初始化,大小就无法修改)。   <李> <>强DelayQueue: DelayQueue对元素进行持有直到一个特定的延迟到期。注入其中的元素必须实现java . util . concurrent。李推迟接口。   <李> <>强LinkedBlockingQueue: LinkedBlockingQueue内部以一个链式结构(链接节点)对其元素进行存储。如果需要的话,这一链式结构可以选择一个上限。如果没有定义上限,将使用整数。李MAX_VALUE作为上限。   <李> <>强PriorityBlockingQueue: PriorityBlockingQueue是一个无界的并发队列。它使用了和类java.util。PriorityQueue一样的排序规则。你无法向这个队列中插入零值。所有插入到PriorityBlockingQueue的元素必须实现. lang。类似的接口。因此该队列中元素的排序就取决于你自己的可比实现。   <李> <>强SynchronousQueue: SynchronousQueue是一个特殊的队列,它的内部同时只能够容纳单个元素。如果该队列已有一元素的话,试图向队列中插入一个新元素的线程将会阻塞,直到另一个线程将该元素从队列中抽走。同样,如果该队列为空,试图向队列中抽取一个元素的线程将会阻塞,直到另一个线程向队列中插入了一条新的元素。据此,把这个类称作一个队列显然是夸大其词了。它更多像是一个汇合点。   
  

使用例子:

  

阻塞队列的最长使用的例子就是生产者消费者模式,也是各种实现生产者消费者模式方式中首选的方式。使用者不用关心什么阻塞生产,什么时候阻塞消费,使用非常方便,代码如下:

        包MyThread;      进口java.util.Random;   进口java.util.concurrent.BlockingQueue;   进口java.util.concurrent.LinkedBlockingQueue;   进口java.util.concurrent.TimeUnit;      公开课BlockingQueueTest {//生产者   公共静态类生产商实现Runnable {   私人最终BlockingQueueblockingQueue;   私人动荡的布尔标志;   私人随机随机;      公共生产商(BlockingQueue

详解Java阻塞队列(BlockingQueue)的实现原理