一,阻塞队列的实现原理:
1)阻塞队列原理:
其实阻塞队列实现阻塞同步的方式很简单,使用的就是:lock锁+多个条件(condition)的阻塞控制。
使用BlockingQueue封装了根据condition条件阻塞线程的过程,使得我们不用去关心繁琐的await/signal操作了。
阻塞队列的最常使用的例子就是生产者消费者模式,也是各种实现生产者消费者模式方式中首选的方式。使用者不用关心什么阻塞生产,什么时候阻塞消费,使用非常方便,
补充:双端阻塞队列(BlockingDeque)
concurrent包下还提供双端阻塞队列(BlockingDeque),和BlockingQueue是类似的,只不过BlockingDeque可以从任意一端,进行插入或者抽取元素。
二,说几种主要的阻塞队列 / BlockingQueue阻塞队列的实现类:
BlockingQueue 是个接口,你需要使用它的实现之一来使用BlockingQueue,
java.util.concurrent包下,具有以下这几个BlockingQueue 接口的实现类:
引用1:
有界队列:有界队列的意思就是,该队列它不能够存储无限多数量的元素。
无界队列:无界队列的意思相反,就是该队列存储的元素数量没有界限;
引用2:
公平的访问队列:
所谓公平的访问队列是指:本来阻塞着的所有生产者线程或者消费者线程,当队列重新变的可用时,可以按照阻塞的先后顺序来访问队列;
即, 先阻塞的生产者线程,可以先往队列中插入元素;
先阻塞的消费者线程,可以先从队列中获取元素;
1)ArrayBlockingQueue:
ArrayBlockingQueue 是一个用数组实现的、有界的阻塞队列,其内部实现是将对象放到一个数组里。有界也就意味着,它不能够存储无限多数量的元素。
它有一个同一时间能够存储元素数量的上限。你可以在对其初始化的时候设定这个上限,但之后就无法对这个上限进行修改了(译者注:因为它是基于数组实现的,也就具有数组的特性:一旦初始化,大小就无法修改)。
此队列按照FIFO(先进先出)的原则对元素进行排序;
是一种默认情况下不保证访问者公平的访问队列;
2)DelayQueue:
这是一种支持延时获取元素的无界阻塞队列;
意思就是,在往DelayQueue队列中存入元素时,可以指定:多久才能从队列中获取当前这些元素,即,延时获取;
队列中的元素必须实现 java.util.concurrent.Delayed 接口。
3)LinkedBlockingQueue:
这是一种基于链表的阻塞队列;即,内部是以链表结构对其元素进行存储。
与ArrayBlockingQueue类似,此队列也是按照FIFO(先进先出)的原则对元素进行排序;
LinkedBlockingQueue可以高效的处理并发数据,因为其对于生产者端和消费者端分别采用了独立的锁来控制数据同步,这也意味着,在高并发的情况下,生产者和消费者可以并行的操作队列中的数据,这样一来大大的提高整个队列的并发性能;
4)PriorityBlockingQueue:
这是一种支持优先级的无界并发队列;
无法向这个队列中插入 null 值。
默认情况下元素采取自然顺序升序排列;
所有插入到 该队列 的元素必须实现 java.lang.Comparable 接口,因此该队列中的元素的排序规则,也可以自定义。
5)SynchronousQueue:
SynchronousQueue 是一个特殊的队列,它的内部同时只能够容纳单个元素。
如果该队列已有一个元素的话,试图向队列中插入(Put)一个新元素的线程将会阻塞,直到另一个线程将该元素从队列中取走(take)。
同样,如果该队列为空,试图向队列中抽取一个元素的线程将会阻塞,直到另一个线程向队列中插入了一条新的元素。