简介

多线程中通过队列很容易共享数据,比方经典的生产者消费者模型中,通过队列能够很不便的实现数据共享。假如咱们有若干生产者线程,又有若干消费者线程,生产者线程能够通过队列将数据共享给消费者。然而生产者和消费者在某个时间段内,万一产生数据处理速度不匹配的状况呢?如果生产者生产数据的速度远大于消费者生产数据的速度,现实状况下是当生产者产生的数据达到一个阈值之后,那么生产者必须暂停一下(阻塞生产者线程),以便消费者能够把数据生产掉。在concurrent包呈现之前,开发人员必须手动管制这些细节,导致开发高性能程序难度较大(兼顾效率和平安)。concurrent进去之后,带来了BlockingQueue(在多线程中,在某些状况下挂起线程(即阻塞),一旦条件满足,被挂起的线程又会被主动唤醒)

BlockingQueue即为阻塞队列,是一个先进先出的队列,在某些状况下,对阻塞队列的拜访可能会造成阻塞,被阻塞的状况次要有两种。
  • 当对列满时,进行入队操作时。当一个线程试图对一个曾经满了的队列进行入队操作时,也将会被阻塞,除非有一个线程进行了出队列操作。
  • 当队列空时,进行出队操作时。当一个线程试图对一个为空的队列进行出队列操作时,也将会被阻塞,费油有一个线程进行了出队列操作。
阻塞队列是线程平安的,次要用在生产者消费者的场景上。负责生产的线程一直的制作新对象并插入到阻塞队列中,直到达到队列的上限值,从而被阻塞,直到生产线程对队列进行生产。同理,负责生产的线程一直的从队列中取出对象进行生产,直到这个队列为空,这时生产队列会被阻塞,除非队列中有新的对象被退出进来。
public interface BlockingQueue<E> extends Queue<E> {}public interface Queue<E> extends Collection<E> {}
BlockingQueue是一个接口,继承自Queue,所以实现类也能够作为Queue的实现来应用,而Queue又继承自Collection接口。

BlockingQueue对插入操作,移除操作,获取元素操作提供了四种不同的办法用于不同的场景,应用不同的办法,会有不同的成果。BlockingQueue的各个实现都遵循这些规定。

Throws ExceptionSpecial ValueBlocksTimes Out
insertadd(o)offer(o)put(o)offer(o,timeout,timeunit)
removeremove(o)poll()take()poll(timeout,timeunit)
examineelement()peek()not applicablenot applicable
  • Throws Exception:抛出异样。如果不能马上进行,则抛出异样。
  • Special Value:如果不能马上进行,则返回非凡值,个别是True或False
  • Blocks:如果不能马上进行,则操作会被阻塞,直到这个操作胜利
  • Times Out:如果不能马上进行,操作会被阻塞指定的工夫。如果指定工夫还未执行,则返回非凡值,个别是True或False。
对于BlockingQueue,关注点应该在它的puttake办法上,因为这两个办法是带阻塞。

BlockingQueue不承受null值的插入,相应的办法在碰到null的插入时会抛出NullPointerException异样,null值通常用于非凡值返回(表格中的第三列),代表poll失败。所以如果容许插入null值的话,那获取的时候,就不能很好的用null来判断到底是失败还是获取的值为null

BlockingQueue实现了java.util.Collection接口,咱们能够应用remove(x)来删除任意一个元素,然而这类操作并不高效,所以尽量在多数场合应用,比方一条音讯曾经入队,然而须要勾销操作的时候。

BlockingQueue的实现都是线程平安的,然而批量的汇合操作addAll,containsAll,retainAll,removeAll不肯定是原子操作,如addAll(c)增加了一些元素后抛出异样,此时BlockingQueue中曾经增加了局部元素,这个是容许的,取决于具体实现。

BlockingQueue在生产者-消费者的场景中,是反对多消费者和多消费者的,说的其实就是线程平安问题。BlockingQueue是一个比较简单的线程平安容器。作为BlockingQueue的使用者,咱们再不必思考何时阻塞线程,什么时候唤醒线程,因为这一些BlockingQueue都实现了。

无界队列,并不是大小不限度,只是它的大小是Integer.MAX_VALUE,即int类型能示意的最大值(2的31次方)-1

BlockingQueue具体实现类

  • ArrayBlockingQueue
  • LinkedBlockingQueue
  • DelayQueue
  • PriorityBlockingQueue
  • SynchronousQueue
罕用的是ArrayBlockingQueueLinkedBlockingQueue

关注微信公众号:【入门小站】,解锁更多知识点。