欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

Java的18种Queue

时间:2023-06-07

Java中的Queue家族,总共涉及到18种Queue:

队列Queue相关知识总结如下:

序号名称类型有界线程安全说明1Queue< E >接口//最上层队列接口2BlockingQueue< E >接口//阻塞队列接口3BlockingDeque< E >接口//双向阻塞队列接口4Deque< E >接口//双向队列接口5TransferQueue< E >接口//传输队列接口6AbstractQueue< E >抽象类//队列抽象类7PriorityQueue< E >普通类NN优先级队列类8ArrayDeque< E >普通类NN数组双向队列类9linkedList< E >普通类NN链表对象类10ConcurrentlinkedQueue< E >普通类NY链表结构的线程安全的队列类11ConcurrentlinkedDeque< E >普通类NY链表结构的线程安全的双向队列类12ArrayBlockingQueue< E >普通类YY数组结构的有界阻塞队列13linkedBlockingQueue< E >普通类YY链表结构的有界阻塞队列14linkedBlockingDeque< E >普通类YY链表结构的双向有界阻塞队列15linkedTransferQueue< E >普通类NY链表组成的无界阻塞传输队列16SynchronousQueue< E >普通类YY不存储元素的阻塞队列17PriorityBlockQueue< E >普通类NY支持优先级排序的无界阻塞队列18DelayQueue< E >普通类NY支持优先级排序,延时的无界阻塞队列 文章目录

一、Queue介绍

1.1 Java集合Queue1.2 Queue现实生活的使用场景1.3 Queue计算机中的场景 二、18种Queue整体介绍三、Queue接口

3.1 深入理解Queue接口的本质3.2 Queue接口的核心方法 四、双端可用Deque接口

4.1 深入理解Deque接口的原理4.2 哪些类实现了Deque接口4.3 哪些类继承了Deque接口 五、队列骨架AbstractQueue抽象类

5.1 深入理解AbstractQueue抽象类5.2 哪些类继承了AbstractQueue抽象类 六、阻塞缓冲BlockingQueue接口

6.1 宏观来看BlockingQueue(阻塞队列)6.2 案例解析6.3 操刀BlockingQueue接口6.4 BlockingQueue通过什么来阻塞插入和移除的?6.5 哪些类继承了BlockingQueue接口?6.6 哪些类实现了BlockingQueue接口?6.7 BlockingQueue接口继承了哪些接口 七、双端阻塞BlockingDeque接口

7.1 从原理图上理解BlockDeque7.2 BlockingDeque接口方法7.3 BlockDeque和BlockQueue的对等方法7.4 BlockingDeque的特点7.5 BlockingDeque接口继承了哪些接口?7.6 哪些类实现了BlockDeque接口? 八、使命必达TransferQueue接口

8.1 Transfer怎么理解?8.2 生活中的案例8.3 TransferQueue的原理解析8.3 TransferQueue接口继承了哪些接口?8.4 哪些类实现了TransferQueue接口? 九、优先由你PriorityQueue类

9.1 理解PriorityQueue类9.2 PriorityQueue类继承了哪些类?9.3 PriorityQueue类实现了哪些接口? 十、双向链表linkedList类

10.1 linkedList的结构10.2 与ArrayList的区别10.3 linkedList不是线程安全的10.4 linkedList的家庭成员关系 十一、并发安全ConcurrentlinkedQueue类

11.1 理解ConcurrentlinkedQueue11.2 ConcurrentlinkedQueue类继承了哪些类?11.3 ConcurrentlinkedQueue类实现了哪些接口? 十二、双向数组ArrayDeque类

12.1 理解ArrayDeque12.2 使用方法12.3 ArrayDeque实现了哪些接口 十三、双向并发ConcurrentlinkedDeque类

13.1 理解ConcurrentlinkedDeque类13.2 ConcurrentlinkedDeque使用示例13.3 ConcurrentlinkedDeque实现了哪些接口 十四、数组阻塞ArrayBlockingQueue类

14.1 理解ArrayBlockingQueue14.2 ArrayBlockQueue实现了哪些接口 十五、链表阻塞linkedBlockingQueue类

15.1 理解linkedBlockingQueue15.2 linkedBlockingQueue使用示例15.3 linkedBlockingQueue的应用场景15.4 linkedBlockingQueue实现了哪些接口 十六、双向阻塞linkedBlockingDeque类

16.1 理解linkedBlockingDeque类16.2 linkedBlockingDeque的应用场景16.3 linkedBlockingDeque实现了哪些接口 十七、链表阻塞linkedTransferQueue类

17.1 理解linkedTransferQueue类17.2 linkedTransferQueue接口比其他阻塞队列多了5个方法17.3 linkedTransferQueue实现了哪些接口 十八、传球好手SynchronousQueue类

18.1 理解SynchronousQueue类18.2 SynchronousQueue应用场景18.3 SynchronousQueue和linkedTransferQueue的区别 十九、优先级阻塞PriorityBlockingQueue类

19.1 理解PriorityBlockQueue类19.2 PriorityBlockQueue实现了哪些接口 二十、延时阻塞DelayQueue类

20.1 理解DelayQueue20.2 应用场景20.3 DelayQueue实现了哪些接口 一、Queue介绍 1.1 Java集合Queue

Queue、队列,是一种数据结构,可以想象成一个数组,元素从一头进入、从另外一头出去,称为FIFO原则(先进先出原则)。

和 List(列表)、Set(集),都是Collection的儿子,还有一个远房亲戚:Map(映射),都是java.util包这个大家庭的成员。

可以参考Java集合的线程不安全的Java集合框架总结的思维导图。

1.2 Queue现实生活的使用场景

海底捞排号等位(先排号的优先进餐厅)邮政员寄送信件(信箱是队列) 1.3 Queue计算机中的场景

消息队列 RabbitMQUDP协议(接收端将消息存放在队列中,从队列中读取数据) 二、18种Queue整体介绍

18种队列分为三大类: 接口、抽象类、普通类。

弄清楚下面的继承实现关系对后面理解18种队列有很大帮助。

Queue接口继承 Collection接口,Collection接口继承 Iterable接口BlockingQueue接口、Deque接口 继承 Queue接口AbstractQueue抽象类实现 Queue接口BlockingDeque接口、TransferQueue接口继承 BlockingQueue接口BlockingDeque接口继承Deque接口linkedBlockingDeque类实现 BlockingDeque接口linkedTransferQueue类接口实现 TransferQueue接口linkedList类、ArrayDeque类、ConcurrentlinkedDeque类实现了Deque接口ArrayBlockingQueue类、linkendBlockingQueue类、linkedBlockingDeque类、linkedTransferQueue类、SynchronousQueue类、PriorityBlockQueue类、DelayQueue类继承了AbstractQueue抽象类和实现了BlockingQueue接口PriorityQueue类和ConcurrentlinkedQueue类继承了AbstractQueue抽象类

注意:

Deque:全称Double-Ended queue,表示双端队列。类实现接口,用implements接口继承接口,用 extends类继承类,用extends 三、Queue接口 3.1 深入理解Queue接口的本质

Queue接口是一种Collection,被设计用于处理之前临时保存在某处的元素。除了基本的Collection操作之外,队列还提供了额外的插入、提取和检查操作。每一种操作都有两种形式:如果操作失败,则抛出一个异常;如果操作失败,则返回一个特殊值(null或false,取决于是什么操作)。队列通常是以FIFO(先进先出)的方式排序元素,但是这不是必须的。只有优先级队列可以根据提供的比较器对元素进行排序或者是采用正常的排序。无论怎么排序,队列的头将通过调用remove()或poll()方法进行移除。在FIFO队列种,所有新的元素被插入到队尾。其他种类的队列可能使用不同的布局来存放元素。每个Queue必须指定排序属性。 3.2 Queue接口的核心方法

总共有3组方法,每一组方法对应两个方法。如下图所示:

比如添加(Insert)元素的动作,会有两种方式:add(e)和offer(e)。如果调用add(e)方法时,添加失败,则会抛异常,而如果调用的是offer(e)方法失败时,则会返回false。offer方法用于异常是正常的情况下使用,比如在有界队列中,优先使用offer方法。假如队列满了,不能添加元素,offer方法返回false,这样我们就知道是队列满了,而不是去handle运行时抛出的异常。

同理,移除(Remove)元素的动作,队列为空时,remove方法抛异常,而poll返回null。如果移除头部的元素成功,则返回移除的元素。

同理,检测(Examine)元素的动作,返回头部元素(最开始加入的元素),但不删除元素, 如果队列为空,则element()方法抛异常,而peek()返回false。

Queue接口没有定义阻塞队列的方法,这些方法在BlockQueue接口中定义了。

Queue实现类通常不允许插入null元素,尽管一些实现类比如linkedList不禁止插入null,但是还是不建议插入null,因为null也被用在poll方法的特殊返回值,以说明队列不包含元素。

四、双端可用Deque接口 4.1 深入理解Deque接口的原理


(1)Deque概念: 支持两端元素插入和移除的线性集合。名称deque是双端队列的缩写,通常发音为deck。大多数实现Deque的类,对它们包含的元素的数量没有固定的限制的,支持有界和无界。

(2)Deque方法说明:

说明:

该列表包含包含访问deque两端元素的方法,提供了插入,移除和检查元素的方法。这些方法种的每一种都存在两种形式:如果操作失败,则会抛出异常,另一种方法返回一个特殊值(null或false,取决于具体操作)。插入操作的后一种形式专门设计用于容量限制的Deque实现,大多数实现中,插入操作不能失败,所以可以用插入操作的后一种形式。Deque接口扩展了Queue接口,当使用deque作为队列时,作为FIFO。元素将添加到deque的末尾,并从头开始删除。作为FIFO时等价于Queue的方法如下表所示:

比如Queue的add方法和Deque的addLast方法等价。Deque也可以用作LIFO(后进先出)栈,这个接口优于传统的Stack类。当作为栈使用时,元素被push到deque队列的头,而pop也是从队列的头pop出来。Stack(栈)的方法正好等同于Deque的如下方法:

注意:peek方法不论是作为栈还是队列,都是从队列检测队列的头,返回最先加入的元素。比如第一次put 100,第二次put 200,则peek返回的是100。 4.2 哪些类实现了Deque接口

linkedList类ArrayDeque类ConcurrentlinkedDeque类linkedBlockingDeque类 4.3 哪些类继承了Deque接口

BlockingDeque接口 五、队列骨架AbstractQueue抽象类 5.1 深入理解AbstractQueue抽象类

AbstractQueue是一个抽象类,继承了Queue接口,提供了一些Queue操作的骨架实现。

方法add、remove、element方法基于offer、poll和peek。也就是说如果不能正常操作,则抛出异常。我们来看下AbstactQueue是怎么做到的。

AbstractQueue的add方法

public boolean add(E e) { if (offer(e)) return true; else throw new IllegalStateException("Queue full");}

AbstractQueue的remove方法

public E remove() { E x = poll(); if (x != null) return x; else throw new NoSuchElementException();}

AbstractQueue的element方法

public E element() { E x = peek(); if (x != null) return x; else throw new NoSuchElementException();}

注意:

如果继承AbstractQueue抽象类则必须保证offer方法不允许null值插入。 5.2 哪些类继承了AbstractQueue抽象类

ArrayBlockingQueue类、linkendBlockingQueue类、linkedBlockingDeque类、linkedTransferQueue类、SynchronousQueue类、PriorityBlockQueue类、DelayQueue类继承了AbstractQueue抽象类PriorityQueue类和ConcurrentlinkedQueue类继承了AbstractQueue抽象类 六、阻塞缓冲BlockingQueue接口 6.1 宏观来看BlockingQueue(阻塞队列)

BlockQueue满了,PUT操作被阻塞
BlockQueue为空,Take操作被阻塞

(1)BlockingQueue(阻塞队列)也是一种队列,支持阻塞的插入和移除方法。

(2)阻塞的插入:当队列满时,队列会阻塞插入元素的线程,直到队列不满。

(3)阻塞的移除:当队列为空,获取元素的线程会等待队列变为非空。

(4)应用场景:生产者和消费者,生产者线程向队列里添加元素,消费者线程从队列里移除元素,阻塞队列时获取和存放元素的容器。

(5)为什么要用阻塞队列:生产者生产和消费者消费的速率不一样,需要用队列来解决速率差问题,当队列满了或空的时候,则需要阻塞生产或消费动作来解决队列满或空的问题。

6.2 案例解析

线程A往阻塞队列(Blocking Queue)中添加元素,而线程B从阻塞队列中移除元素。

当阻塞队列为空的时候 (一个元素都没有),则从队列中获取元素的操作将会被阻塞。

生活中的案例:去海底捞吃火锅的时候,早上8点没人来吃火锅,所以需要等客人过来。翻译成线程:现在没有元素需要添加,而且阻塞队列为空,所以线程B不需要从队列中拿元素出来,所以线程B获取元素的操作被阻塞了。 当阻塞队列满了的时候 (所有位置都放有元素),则从队列中添加元素的操作将会被阻塞。

生活中的案例:去海底捞吃火锅的时候,人太多了,需要排号,等其他桌空出来了才能进去。翻译成线程:线程A往阻塞队列中添加元素,将队列填满了,线程B现在正在忙,无法拿出队列中的元素,所以阻塞队列没有地方再放元素了,这个时候线程A添加元素的操作就被阻塞了 6.3 操刀BlockingQueue接口

BlockingQueue接口的10个核心方法:

10个核心方法总结如下:

有三大类操作:插入、移除、检查。

(1)插入有四种方法: add、offer、put、offer超时版。

add方法特别之处用于添加失败时抛出异常,共有四种异常:

IllegalStateException - 队列满了ClassCastException - 添加的元素类型不匹配NullPointerException - 添加的元素为nullIllegalArgumentException - 添加的元素某些属性不匹配 offer方法特别之处用于添加失败时只返回falseput方法特别之处用于当阻塞队列满时,生产者如果往队列里put元素,则队列会一直阻塞生产者线程,直到队列可用或者响应中断退出offer超时方法特别之处用于当阻塞队列满时,生产者如果往队列里面插入元素,队列会阻塞生产者线程一段时间,如果超过了指定时间,生产者线程会退出,并返回false。

(2)移除有四种方法: remove、poll、take、poll超时版

remove方法特别之处用于移除失败时抛出异常

NoSuchElementException - 如果这个队列是空的 poll方法特别之处用于移除失败时返回nulltake方法特别之处用于当阻塞队列为空时,消费者线程如果从队列里面移除元素,则队列会一直阻塞消费者线程,直到队列不为空poll超时方法特别之处用于当阻塞队列空时,消费者如果从队列里面删除元素,则队列会一直阻塞消费者线程,如果超过了指定时间,消费者线程会退出,并返回null

(3)检查有两种方法: element、peek

element方法用于检测头部元素的存在性,如果队列为空,则抛出异常,否则返回头部元素。peek方法用于检测头部元素的存在性,如果队列为空,返回特殊值null,否则返回头部的元素。 6.4 BlockingQueue通过什么来阻塞插入和移除的?

当往队列里插入一个元素时,如果队列不可用,那么阻塞生产者主要通过LockSupport、park(this)来实现。

park这个方法会阻塞当前线程,只有以下4种情况中的一种发生时,该方法才会返回。

与park对应的unpark执行或已经执行时。“已经执行”是指unpark先执行,然后再执行park的情况。线程被中断时。等待完time参数指定的毫秒数时。异常现象发生时,这个异常现象没有任何原因。 6.5 哪些类继承了BlockingQueue接口?

BlockingDeque接口 - 双端阻塞队列TransferQueue接口 - 传输队列 6.6 哪些类实现了BlockingQueue接口?

ArrayBlockingQueue类 - 由数组构成的有界阻塞队列linkedBlockingQueue类 -由链表构成的有界阻塞队列,界限默认大小为Integer.MAX_Value(2^31-1),值非常大,相当于无界。linkedBlockingDeque类 - 由链表构成的双向阻塞队列linkedTransferQueue类 - 由链表构成的无界阻塞队列SynchronousQueue类 - 不存储元素的阻塞队列,只有一个元素进行数据传递。linkedTransferQueue类 - 由链表构成的无界阻塞TransferQueue队列DelayQueue类 - 使用优先级队列实现的延迟无界阻塞队列 6.7 BlockingQueue接口继承了哪些接口

BlockingQueue接口继承了Queue接口,可作为队列使用 七、双端阻塞BlockingDeque接口 7.1 从原理图上理解BlockDeque

BlockQueue满了,两端的Take操作被阻塞
BlockQueue为空,两端的Take操作被阻塞
7.2 BlockingDeque接口方法

是阻塞队列BlockingQueue和双向队列Deque接口的结合。有如下方法:

7.3 BlockDeque和BlockQueue的对等方法 7.4 BlockingDeque的特点

线程安全。不允许使用null元素。无界和有界都可以。 7.5 BlockingDeque接口继承了哪些接口?

Queue接口,具有队列的功能Deque接口,具有双端队列的功能BlockingQueue接口,可作为阻塞队列使用 7.6 哪些类实现了BlockDeque接口?

linkedBlockingDeque 八、使命必达TransferQueue接口 8.1 Transfer怎么理解?

如果有消费者正在获取元素,则将队列中的元素传递给消费者。如果没有消费者,则等待消费者消费。我把它称作使命必达队列,必须将任务完成才能返回。

8.2 生活中的案例

针对TransferQueue的transfer方法

圆通快递员要将小明的2个快递送货到门,韵达快递员也想将小明的2个快递送货到门。小明一次只能拿一个,快递员必须等小明拿了一个后,才能继续给第二个。

针对TransferQueue的tryTransfer方法

圆通快递员要将小明的2个快递送货到门,韵达快递员也想将小明的2个快递送货到门。发现小明不在家,就把快递直接放到菜鸟驿站了。

针对TransferQueue的tryTransfer超时方法

圆通快递员要将小明的2个快递送货到门,韵达快递员也想将小明的2个快递送货到门。发现小明不在家,于是先等了5分钟,发现小明还没有回来,就把快递直接放到菜鸟驿站了。 8.3 TransferQueue的原理解析

transfer(E e)

原理如下图所示:

8.3 TransferQueue接口继承了哪些接口?

BlockingQueue接口,可作为阻塞队列使用Queue接口,可作为队列使用 8.4 哪些类实现了TransferQueue接口?

linkedTranferQueue接口 九、优先由你PriorityQueue类 9.1 理解PriorityQueue类

本应该按照升序排序
按照倒叙排序
PriorityQueue是一个支持优先级的无界阻塞队列。默认自然顺序升序排序。可以通过构造参数Comparator来对元素进行排序。

public PriorityQueue(Comparator<? super E> comparator) { this(DEFAULT_INITIAL_CAPACITY, comparator);}

自定义实现comapreTo()方法来指定元素排序规则。

public Comparator<? super E> comparator() { return comparator;}

不允许插入null元素。实现PriorityQueue接口的类,不保证线程安全,除非是PriorityBlockingQueue。PriorityQueue的迭代器不能保证以任何特定顺序遍历元素,如果需要有序遍历,请考虑使用Arrays.sort(pq.toArray)。进列(offer、add)和出列( poll、remove())的时间复杂度O(log(n))。remove(Object) 和 contains(Object)的算法时间复杂度O(n)。peek、element、size的算法时间复杂度为O(1)。 9.2 PriorityQueue类继承了哪些类?

AbstractQueue抽象类,具有队列的功能 9.3 PriorityQueue类实现了哪些接口?

Queue接口,可作为队列使用。 十、双向链表linkedList类 10.1 linkedList的结构

linkedList实现了List和Deque接口,所以是一种双链表结构,可以当作堆栈、队列、双向队列使用。一个双向列表的每一个元素都有三个整数值:元素、向后的节点链接、向前的节点链接

来看下节点类Node

private static class Node { E item; //元素 Node next; //向后的节点链接 Node prev; //向前的节点链接 Node(Node prev, E element, Node next) { this.item = element; this.next = next; this.prev = prev; }}

10.2 与ArrayList的区别

linkedList的增加和删除效率相对较高,而查找和修改的效率相对较低。

以下情况建议使用ArrayList

频繁访问列表中的一个元素。只在列表的首尾添加元素。

以下情况建议使用linkedList

频繁地在列表开头、中间、末尾添加和删除元素。

需要通过循环迭代来访问列表中的元素。

10.3 linkedList不是线程安全的

linkedList不是线程安全的,所以可以使用如下方式保证线程安全。

List list = Collections.synchronizedList(new linkedList<>());

10.4 linkedList的家庭成员关系

linkedList 继承了 AbstractSequentialList 类。linkedList 实现了 Queue 接口,可作为队列使用。linkedList 继承了 AbstractQueue抽象类,具有队列的功能。linkedList 实现了 List 接口,可进行列表的相关操作。linkedList 实现了 Deque 接口,可作为双向队列使用。linkedList 实现了 Cloneable 接口,可实现克隆。linkedList 实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。 十一、并发安全ConcurrentlinkedQueue类 11.1 理解ConcurrentlinkedQueue

Concurrentlinked是由链表结构组成的线程安全的先进先出无界队列。当多线程要共享访问集合时,ConcurrentlinkedQueue是一个比较好的选择。不允许插入null元素支持非阻塞地访问并发安全的队列,不会抛出ConcurrentModifiationException异常。size方法不是准确的,因为在统计集合的时候,队列可能正在添加元素,导致统计不准。批量操作addAll、removeAll、retainAll、containsAll、equals和toArray不保证原子性(操作不可分割)添加元素happen-before其他线程移除元素。

用法如下:

ConcurrentlinkedQueue queue = new ConcurrentlinkedQueue();BuildingBlockWithName buildingBlock = new BuildingBlockWithName("三角形", "A");concurrentlinkedQueue.add(buildingBlock);

11.2 ConcurrentlinkedQueue类继承了哪些类?

AbstractQueue抽象类,具有队列的功能 11.3 ConcurrentlinkedQueue类实现了哪些接口?

Queue接口,可作为队列使用 十二、双向数组ArrayDeque类 12.1 理解ArrayDeque

由数组组成的双端队列。没有容量限制,根据需要扩容。不是线程安全的。禁止插入null元素。当用作栈时,比栈速度快,当用作队列时,速度比linkList快。大部分方法的算法时间复杂度为O(1)。remove、removeFirstOccurrence、removeLastOccurrence、contains、remove和批量操作的算法时间复杂度O(n) 12.2 使用方法

创建一个ArrayDeque,往arrayDeque队尾添加元素。

ArrayDeque arrayDeque = new ArrayDeque();for (int i = 0; i < 50; i++) { arrayDeque.add(buildingBlock); // add方法等价于addLast方法}

12.3 ArrayDeque实现了哪些接口

Deque接口 - 可用于双端队列 十三、双向并发ConcurrentlinkedDeque类 13.1 理解ConcurrentlinkedDeque类

由链表结构组成的双向无界阻塞队列插入、删除和访问操作可以并发进行,线程安全的类不允许插入null元素在并发场景下,计算队列的大小是不准确的,因为计算时,可能有元素加入队列。批量操作addAll、removeAll、retainAll、containsAll、equals和toArray不保证原子性(操作不可分割) 13.2 ConcurrentlinkedDeque使用示例

创建两个积木:三角形、四边形,然后添加到队列:

BuildingBlockWithName buildingBlock1 = new BuildingBlockWithName("三角形", "A");BuildingBlockWithName buildingBlock2 = new BuildingBlockWithName("四边形", "B");ConcurrentlinkedDeque concurrentlinkedDeque = new ConcurrentlinkedDeque();concurrentlinkedDeque.addFirst(buildingBlock1);concurrentlinkedDeque.addLast(buildingBlock2);//结果:顺序:三角形、四边形

13.3 ConcurrentlinkedDeque实现了哪些接口

Deque接口 - 可用于双端队列 十四、数组阻塞ArrayBlockingQueue类 14.1 理解ArrayBlockingQueue

ArrayBlockingQueue是一个用数组实现的有界阻塞队列。队列慢时插入操作被阻塞,队列空时,移除操作被阻塞。按照先进先出(FIFO)原则对元素进行排序。默认不保证线程公平的访问队列。公平访问队列:按照阻塞的先后顺序访问队列,即先阻塞的线程先访问队列。非公平性是对先等待的线程是非公平的,当队列可用时,阻塞的线程都可以争夺访问队列的资格。有可能先阻塞的线程最后才访问访问队列。公平性会降低吞吐量。 14.2 ArrayBlockQueue实现了哪些接口

Deque接口 - 可用于双端队列 十五、链表阻塞linkedBlockingQueue类 15.1 理解linkedBlockingQueue

linkedBlockingQueue具有单链表和有界阻塞队列的功能。队列慢时插入操作被阻塞,队列空时,移除操作被阻塞。默认和最大长度为Integer.MAX_VALUE,相当于无界(值非常大:2^31-1)。 15.2 linkedBlockingQueue使用示例

linkedList linkedList1 = new linkedList();linkedList1.add("A");linkedList1.add("B");linkedList1.add("C");

15.3 linkedBlockingQueue的应用场景

吞吐量通常要高于ArrayBlockingQueue。创建线程池时,参数runnableTaskQueue(任务队列),用于保存等待执行的任务的阻塞队列可以选择linkedBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。 15.4 linkedBlockingQueue实现了哪些接口

linkedBlockingQueue继承了 BlockingQueue类,可作为阻塞队列使用linkedBlockingQueue继承了 AbstractQueue抽象类,具有队列的功能。linkedBlockingQueue实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。 十六、双向阻塞linkedBlockingDeque类 16.1 理解linkedBlockingDeque类

由链linkedBlockingDeque = 阻塞队列+链表+双端访问线程安全。多线程同时入队时,因多了一端访问入口,所以减少了一半的竞争。默认容量大小为Integer.MAX_VALUE。可指定容量大小。 16.2 linkedBlockingDeque的应用场景

linkedBlockingDeque可以用在“工作窃取“模式中。

工作窃取算法:某个线程比较空闲,从其他线程的工作队列中的队尾窃取任务来帮忙执行。

16.3 linkedBlockingDeque实现了哪些接口

linkedBlockingDeque继承了 BlockingDeque类,可作为阻塞队列使用linkedBlockingDeque继承了 AbstractQueue抽象类,具有队列的功能。linkedBlockingDeque实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。 十七、链表阻塞linkedTransferQueue类 17.1 理解linkedTransferQueue类


linkedTransferQueue = 阻塞队列+链表结构+TransferQueue

之前我们讲使命必达TransferQueue接口时已经介绍过了TransferQueue接口 ,所以linkedTransferQueue接口跟它相似,只是加入了阻塞插入和移除的功能,以及结构是链表结构。

之前的TransferQueue也讲到了3个案例来说明TransferQueue的原理,大家可以回看TransferQueue。

17.2 linkedTransferQueue接口比其他阻塞队列多了5个方法

transfer(E e)tryTransfer(E e)tryTransfer(E e, long timeout, TimeUnit unit)getWaitingConsumerCount()hasWaitingConsumer() 17.3 linkedTransferQueue实现了哪些接口

linkedBlockingDeque继承了 BlockingQeque类,可作为阻塞队列使用linkedBlockingDeque继承了 AbstractQueue抽象类,具有队列的功能。 十八、传球好手SynchronousQueue类 18.1 理解SynchronousQueue类

我称SynchronousQueue为”传球好手“。想象一下这个场景:小明抱着一个篮球想传给小花,如果小花没有将球拿走,则小明是不能再拿其他球的。SynchronousQueue负责把生产者产生的数据传递给消费者线程。SynchronousQueue本身不存储数据,调用了put方法后,队列里面也是空的。每一个put操作必须等待一个take操作完成,否则不能添加元素。适合传递性场景。性能高于ArrayBlockingQueue和linkedBlockingQueue。 18.2 SynchronousQueue应用场景

吞吐量通常要高于linkedBlockingQueue。创建线程池时,参数runnableTaskQueue(任务队列),用于保存等待执行的任务的阻塞队列可以选择SynchronousQueue。静态工厂方法Executors.newCachedThreadPool()使用了这个队列 18.3 SynchronousQueue和linkedTransferQueue的区别

SynchronousQueue 不存储元素,而linkedTransferQueue存储元素。SynchronousQueue 队列里面没有元素,而linkedTransferQueue可以有多个存储在队列等待传输。linkedTransferQueue还支持若传输不了,则丢到队列里面去。linkedTransferQueue还支持若超过一定时间传输不了,则丢到队列里面去。 十九、优先级阻塞PriorityBlockingQueue类 19.1 理解PriorityBlockQueue类

PriorityBlockQueue = PriorityQueue + BlockingQueue之前我们也讲到了PriorityQueue的原理,支持对元素排序。元素默认自然排序。可以自定义CompareTo()方法来指定元素排序规则。可以通过构造函数构造参数Comparator来对元素进行排序。 19.2 PriorityBlockQueue实现了哪些接口

linkedBlockingQueue继承了 BlockingQueue接口,可作为阻塞队列使用linkedBlockingQueue继承了 AbstractQueue抽象类,具有队列的功能。linkedBlockingQueue实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。 二十、延时阻塞DelayQueue类 20.1 理解DelayQueue

DelayQueue = Delayed + BlockingQueue。队列中的元素必须实现Delayed接口。

public class DelayQueue extends AbstractQueue implements BlockingQueue {

在创建元素时,可以指定多久可以从队列中获取到当前元素。只有在延时期满才能从队列中获取到当前元素。 20.2 应用场景

缓存系统的设计:可以用DelayQueue保存缓存元素的有效期。然后用一个线程循环的查询DelayQueue队列,一旦能从DelayQueue中获取元素时,表示缓存有效期到了。定时任务调度:使用DelayQueue队列保存当天将会执行的任务和执行时间,一旦从DelayQueue中获取到任务就开始执行。比如Java中的TimerQueue就是使用DelayQueue实现的。 20.3 DelayQueue实现了哪些接口

DelayQueue实现了 BlockingQueue接口,可作为阻塞队列使用

参考:

干货-45张图庖丁解牛18种Queue,你知道几种?

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。