(八) Java多线程详解之阻塞队列BlockingQueue及队列优先级详解

来源:互联网 发布:域名的意义 编辑:程序博客网 时间:2024/06/08 19:27

1.关于阻塞队列
阻塞队列与普通队列的区别在于当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来

2.BlockingQueue的操作方法
BlockingQueue的操作方法

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

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

3.BlockingQueue几种子类实现:

3.1 ArrayBlockingQueue:一个有界的阻塞队列,其内部实现是将对象放到一个数组里,有界也就意味着,它不能够存储无限多数量的元素,它有一个同一时间能够存储元素数量的上限。(因为它是基于数组实现的,一旦初始化,大小就无法修改)

3.2 DelayQueue:对元素进行持有直到一个特定的延迟到期。注入其中的元素必须实现java.util.concurrent.Delayed接口

3.3 LinkedBlockingQueue:内部以一个链式结构(链接节点)对其元素进行存储,如果需要的话这一链式结构可以选择一个上限,如果没有定义上限,将使用Integer.MAX_VALUE作为上限

3.4 PriorityBlockingQueue:一个无界的并发队列,它使用了和类java.util.PriorityQueue一样的排序规则,你无法向这个队列中插入null值,所有插入到PriorityBlockingQueue的元素必须实现java.lang.Comparable接口。因此该队列中元素的排序就取决于你自己的Comparable实现

3.5 SynchronousQueue:一个特殊的队列,它的内部同时只能够容纳单个元素,如果该队列已有一元素的话,试图向队列中插入一个新元素的线程将会阻塞,直到另一个线程将该元素从队列中抽走。同样,如果该队列为空,试图向队列中抽取一个元素的线程将会阻塞,直到另一个线程向队列中插入了一条新的元素

4.队列优先级
这里详细讲一下PriorityBlockingQueue,因为在实际需求中可能会遇到希望后入队的对象先出队,面对这种需求,我首先向到的是能不能在队列指定位置添加元素,来控制出队的顺序,遗憾队列是线性结构,只能在队尾位置进行插入元素,队头位置插入元素,但是PriorityBlockingQueue可能通过实现Comparable接口,来修改出队优先级。示例代码如下:

public class ThreadExample20 {    public static void main(String[] args) {        Comparator<Integer> comparator = new Comparator<Integer>() {            public int compare(Integer param, Integer param2) {                if (param > param2) {                    return 1;                } else if (param < param2) {                    return -1;                } else {                    return 0;                }            }        };        BlockingQueue<Integer> blockingQueue = new PriorityBlockingQueue<>(5, comparator);        try {            blockingQueue.put(1);            blockingQueue.put(23);            blockingQueue.put(56);            blockingQueue.put(15);            blockingQueue.put(8);        } catch (InterruptedException e) {            e.printStackTrace();        }        while (true) {            try {                System.out.println(blockingQueue.take());            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}程序运行结果:18152356
原创粉丝点击