飞道的博客

美女同事在公交车上跟我说的话(又名:队列结构详解及Java常见队列结构的实现)

348人阅读  评论(0)

忙碌了一天终于到了下班的时间,Baldwin看表刚过七点,立即就打了卡准备回家,在前往公司班车站的路上,一声清脆的声音响起“Hi~Baldwin,这么早就下班啦!一起回去呗?”原来是公司人事部刚来的美女同事小丽,她跟Baldwin的家相隔不远,都是坐同一辆班车回家。

能跟美女一起回家,Baldwin自然还是很开心的,就边走边聊,奈何小丽走得着实太慢,到班车点的时候都已经排起了长长的队伍,Baldwin一看这么长的队伍,心想肯定赶不上兄弟们开黑了,就拿出手机给几个基友发消息。

小丽此时仔细打量眼前这个男人,虽然身高不到170,体重将近130,下巴上还带着些许胡茬,但在这月光的照射下竟也变得无比高大,心中不觉的生出一片涟漪,情不自禁地低下头,娇羞地说道“Baldwin,我家里不知何时跑进了几只老鼠,人家一个小女生单独在家真的好怕怕,你今晚能到我家,帮我抓老鼠么?”

只见此时那Baldwin正专心致志的与他的朋友聊天,哪顾得去听小丽说的这些话,小丽见Baldwin不言语,以为自己失了态,便也一眼不发地跟着那SBBaldwin。

上车后,他俩并肩走到最后排坐下,小丽便想开口解释一番,对Baldwin说道“刚才我们排队的时候我说的那些话,请别放在心上,我实在无意叨扰,只是不知觉地。。。说了出口”,Baldwin哪里懂得小丽所言何事,但又不敢细问,于是慌不忙地转移话题,说道“唉你一说排队,我就想到了队列结构,你看咱们咱们刚才排队的时候不就是典型的队列么”,小丽睁大眼睛,完全不知道此时Baldwin在讲些什么,Baldwin见此情形恍然大悟,对小丽说道“忘记了你不会编程,那我今天详细的跟你讲一讲队列结构吧!”

一、相关

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素的队列称之为空队列

小丽你看,我们刚才排的队就是一个队列,第一个去排队的人,肯定是第一个上车的人。

总结:FIFO(First in first out)

二、队列的使用情景

一般情况下,如果发送来的消息是及时的,而且处理这些消息无需消耗太多时间。这种情形下是不需要引入队列来处理的,直接选用阻塞式的方法调用即可。

如果处理消息消耗时间非常长,选用阻塞式消息处理的话,新消息来的时候就会处于阻塞状态,用户可能处于长时间的等待状态,这个时候就需要引入队列,用户消息到达后先将消息放入消息队列中,然后用并行的线程处理。

三、队列类型

队列大类可分为两种:顺序队列、循环队列

顺序队列:顺序队列用一个向量空间来存放当前队列中的元素。由于队列的队头和队尾的位置是变化的,设置两个指针front和rear分别指示队头元素和队尾元素在向量空间中的位置,它们的初值在队列初始化时均应设置为0。

循环队列:循环队列是把顺序队列首尾相连,把存储队列元素的表从逻辑上看成一个环,成为循环队列。循环队列避免了顺序队列的假溢出现象。可以将循环队列想象成一个圆环。

四、阻塞队列与普通队列的区别

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

  1. ArrayDeque, (数组双端队列)

  2. ArrayBlockingQueue, (基于数组的并发阻塞队列)

  3. ConcurrentLinkedQueue, (基于链表的并发队列)

  4. DelayQueue, (延期阻塞队列)(阻塞队列实现了BlockingQueue接口)

  5. LinkedBlockingQueue, (基于链表的FIFO阻塞队列)

  6. LinkedBlockingDeque, (基于链表的FIFO双端阻塞队列)

  7. LinkedTransferQueue, (基于链表无界的阻塞队列)

  8. PriorityQueue, (优先级队列)

  9. PriorityBlockingQueue, (带优先级的无界阻塞队列)

  10. SynchronousQueue (并发同步阻塞队列)

五、队列的实现

1.Queue接口

继承关系

Jdk提供了现成的Queue接口来实现队列结构,Queue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了Deque接口

Queue提供了两组常用操作队列元素的方法:

第一组


  
  1. import java.util.LinkedList;
  2. import java.util.Queue;
  3. /**
  4. * 类描述
  5. *
  6. * @author: 12405
  7. * @date: 2020/3/20-22:43
  8. */
  9. public class MyQueue {
  10. public static void main(String[] args) {
  11. Queue<String> myQueue = new LinkedBlockingDeque<>();
  12. myQueue.add( "Baldwin"); //向队列中添加元素
  13. myQueue.add( "Jack");
  14. myQueue.add( "Rose");
  15. System.out.println(myQueue);
  16. System.out.println(myQueue.remove()); //从队列中获取队首的元素并移除
  17. System.out.println(myQueue);
  18. System.out.println(myQueue.element()); //获取队尾的元素并移除
  19. System.out.println(myQueue);
  20. }
  21. }

  
  1. "C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\tools\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=53587:E:\tools\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;E:\Workspaces\IdeaProjects\DemoTest\out\production\DemoTest" cn.yzstu.queuetest.MyQueue
  2. [Baldwin, Jack, Rose]
  3. Baldwin
  4. [Jack, Rose]
  5. Jack
  6. [Jack, Rose]
  7. Process finished with exit code 0

第一组我们提到的三个方法失败时会抛出异常,这是与第二组最主要的 不同。

第二组


  
  1. import java.util.LinkedList;
  2. import java.util.Queue;
  3. /**
  4. * 类描述
  5. *
  6. * @author: 12405
  7. * @date: 2020/3/20-22:43
  8. */
  9. public class MyQueue {
  10. public static void main(String[] args) {
  11. Queue<String> myQueue = new LinkedBlockingDeque<>();
  12. myQueue.offer( "Baldwin"); //向队列中添加元素
  13. myQueue.offer( "Jack");
  14. myQueue.offer( "Rose");
  15. System.out.println(myQueue);
  16. System.out.println(myQueue.poll()); //从队列中获取队首的元素并移除
  17. System.out.println(myQueue);
  18. System.out.println(myQueue.peek()); //获取队尾的元素并移除
  19. System.out.println(myQueue);
  20. }
  21. }

  
  1. "C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\tools\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=53621:E:\tools\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF -8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;E:\Workspaces\IdeaProjects\DemoTest\out\production\DemoTest" cn.yzstu.queuetest.MyQueue
  2. [ Baldwin, Jack, Rose]
  3. Baldwin
  4. [ Jack, Rose]
  5. Jack
  6. [ Jack, Rose]
  7. Process finished with exit code 0

第二组与第一组打印的结果是一样的,现在我们来实验一下如果发生错误会出现什么情况


  
  1. import java.util.LinkedList;
  2. import java.util.Queue;
  3. /**
  4. * 类描述
  5. *
  6. * @author: 12405
  7. * @date: 2020/3/20-22:43
  8. */
  9. public class MyQueue {
  10. public static void main(String[] args) {
  11. Queue<String> myQueue = new LinkedBlockingDeque<>();
  12. System.out.println(myQueue.poll());
  13. System.out.println(myQueue.remove());
  14. }
  15. }

 


  
  1. "C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\tools\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=54818:E:\tools\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF -8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;E:\Workspaces\IdeaProjects\DemoTest\out\production\DemoTest" cn.yzstu.queuetest.MyQueue
  2. null
  3. Exception in thread "main" java.util.NoSuchElementException
  4. at java.util.concurrent.LinkedBlockingDeque.removeFirst(LinkedBlockingDeque. java: 453)
  5. at java.util.concurrent.LinkedBlockingDeque.remove(LinkedBlockingDeque. java: 672)
  6. at cn.yzstu.queuetest.MyQueue.main(MyQueue. java: 18)
  7. Process finished with exit code 1

对一个空队列进行取出队首数据,poll方法返回了一个null,而remove方法直接跳出异常。

实际上,对于第二组操作来说,成功返回true,失败时返回一个特殊值(取决于操作,为NULL或false),offer(E e)操作是专为容量受限的队列实现而设计的;在大多数实现中,插入操作不会失败。

2.ArrayDeque队列

继承关系

底层

ArrayDeque使用数组实现。

在使用过程中没有大小限制,采用自动扩容机制,初始容量为16(详情见ArrayDeque源码)

ArrayDeque是线程不安全的

作为双端队列,其可以在队首或队尾进行插入、取出操作

元素不可为空

常用方法


  
  1. //插入元素
  2. boolean add(E e)
  3. Inserts the specified element at the end of this deque.
  4. void addFirst(E e)
  5. Inserts the specified element at the front of this deque.
  6. void addLast(E e)
  7. Inserts the specified element at the end of this deque.
  8. //插入元素 ,还是调用上面的add方法
  9. boolean offer(E e)
  10. Inserts the specified element at the end of this deque.
  11. boolean offerFirst(E e)
  12. Inserts the specified element at the front of this deque.
  13. boolean offerLast(E e)
  14. Inserts the specified element at the end of this deque.
  15. //获取元素,但是不删除元素
  16. E element()
  17. Retrieves, but does not remove, the head of the queue represented by this deque.
  18. E getFirst()
  19. Retrieves, but does not remove, the first element of this deque.
  20. E getLast()
  21. Retrieves, but does not remove, the last element of this deque.
  22. //获取元素并删除
  23. E poll()
  24. Retrieves and removes the head of the queue represented by this deque (in other words, the first element of this deque), or returns null if this deque is empty.
  25. E pollFirst()
  26. Retrieves and removes the first element of this deque, or returns null if this deque is empty.
  27. E pollLast()
  28. Retrieves and removes the last element of this deque, or returns null if this deque is empty.

实践

队列的取空队列操作,Queue接口方法特性


  
  1. import java.util.ArrayDeque;
  2. import java.util.Queue;
  3. /**
  4. * 类描述
  5. *
  6. * @author: 12405
  7. * @date: 2020/3/20-22:43
  8. */
  9. public class MyQueue {
  10. public static void main(String[] args) {
  11. Queue<String> myQueue = new ArrayDeque<>();
  12. System.out.println(myQueue.poll());
  13. System.out.println(myQueue.remove());
  14. }
  15. }

  
  1. "C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\tools\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=54954:E:\tools\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF -8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;E:\Workspaces\IdeaProjects\DemoTest\out\production\DemoTest" cn.yzstu.queuetest.MyQueue
  2. null
  3. Exception in thread "main" java.util.NoSuchElementException
  4. at java.util.ArrayDeque.removeFirst(ArrayDeque. java: 285)
  5. at java.util.ArrayDeque.remove(ArrayDeque. java: 452)
  6. at cn.yzstu.queuetest.MyQueue.main(MyQueue. java: 17)
  7. Process finished with exit code 1

3.ArrayBlockingQueue队列

继承关系

底层

ArrayBlockingDeque使用数组实现。

未定义初始容量大小,需使用者自行设置,队列满则阻塞(详情见ArrayBlockingDeque源码)

ArrayBlockingQueue 进队操作采用了加锁的方式保证并发安全。

作为双端队列,其可以在队首或队尾进行插入、取出操作

不支持空元素

常用方法


  
  1. public boolean add(E e)
  2. public boolean offer (E e)
  3. public void put (E e) throws InterruptedException
  4. public E poll ()
  5. public E take () throws InterruptedException
  6. public E peek ()
  7. /**
  8. *Returns the number of additional elements that this queue can ideally
  9. * (in the absence of memory or resource constraints) accept without
  10. * blocking.
  11. */
  12. public int remainingCapacity ()

实践

ArrayBlockingQueue阻塞实验


  
  1. import java.util.Queue;
  2. import java.util.concurrent.ArrayBlockingQueue;
  3. /**
  4. * 类描述
  5. *
  6. * @author: 12405
  7. * @date: 2020/3/20-22:43
  8. */
  9. public class MyQueue {
  10. public static void main( String[] args) {
  11. Queue< String> myQueue = new ArrayBlockingQueue< String>( 2);
  12. myQueue.offer( "1");
  13. myQueue.offer( "2");
  14. myQueue.offer( "3");
  15. myQueue.offer( "4");
  16. myQueue.offer( "5");
  17. System.out.println(myQueue);
  18. }
  19. }

  
  1. "C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\tools\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=55297:E:\tools\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;E:\Workspaces\IdeaProjects\DemoTest\out\production\DemoTest" cn.yzstu.queuetest.MyQueue
  2. [1, 2]
  3. Process finished with exit code 0

空元素实验


  
  1. import java.util.Queue;
  2. import java.util.concurrent.ArrayBlockingQueue;
  3. /**
  4. * 类描述
  5. *
  6. * @author: 12405
  7. * @date: 2020/3/20-22:43
  8. */
  9. public class MyQueue {
  10. public static void main(String[] args) {
  11. Queue<String> myQueue = new ArrayBlockingQueue<String>( 2);
  12. myQueue.offer( null);
  13. System.out.println(myQueue);
  14. }
  15. }

  
  1. "C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\tools\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=55367:E:\tools\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF -8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;E:\Workspaces\IdeaProjects\DemoTest\out\production\DemoTest" cn.yzstu.queuetest.MyQueue
  2. Exception in thread "main" java.lang.NullPointerException
  3. at java.util.concurrent.ArrayBlockingQueue.checkNotNull(ArrayBlockingQueue. java: 150)
  4. at java.util.concurrent.ArrayBlockingQueue.offer(ArrayBlockingQueue. java: 325)
  5. at cn.yzstu.queuetest.MyQueue.main(MyQueue. java: 15)
  6. Process finished with exit code 1

4.ConcurrentLinkedQueue队列

继承关系

底层

以链表为底层数据结构

无界,不可指定初始容量大小,元素不为null

使用CAS实现并发安全

与 ConcurrentLinkedQueue 的区别是该阻塞队列同时支持FIFO和FILO两种操作方式,即可以从队列的头和尾同时操作(插入/删除)

常用方法


  
  1. add(E e):在此 deque的尾部插入指定的元素,返回值为Boolean。
  2. addFirst(E e):在此 deque前面插入指定的元素。
  3. addLast(E e):在此 deque的末尾插入指定的元素。
  4. clear():从这个 deque中删除所有的元素。
  5. contains(Object o):返回 true如果这个 deque包含至少一个元素 e ,返回值为Boolean。
  6. descendingIterator():以相反的顺序返回此 deque中的元素的迭代器,返回值为Iterator。
  7. element():检索但不删除由此 deque表示的队列的头部(换句话说,该 deque的第一个元素)。
  8. getFirst():检索,但不删除,这个 deque的第一个元素。
  9. getLast():检索,但不删除,这个 deque的最后一个元素。
  10. isEmpty():如果此集合不包含元素,则返回 true
  11. iterator():以正确的顺序返回此 deque中的元素的迭代器,返回值为Iterator 。
  12. offer(E e):在此 deque的尾部插入指定的元素,返回值为boolean。
  13. offerFirst(E e):在此 deque前面插入指定的元素,返回值为boolean。
  14. offerLast(E e):在此 deque的末尾插入指定的元素,返回值为boolean。
  15. peek():检索但不删除由此 deque表示的队列的头(换句话说,该 deque的第一个元素),如果此 deque为空,则返回 null 。
  16. peekFirst():检索但不删除此 deque的第一个元素,如果此 deque为空,则返回 null 。
  17. peekLast():检索但不删除此 deque的最后一个元素,如果此 deque为空,则返回 null 。
  18. poll():检索并删除由此 deque表示的队列的头部(换句话说,该 deque的第一个元素),如果此 deque为空,则返回 null 。
  19. pollFirst():检索并删除此 deque的第一个元素,如果此 deque为空,则返回 null 。
  20. pollLast():检索并删除此 deque的最后一个元素,如果此 deque为空,则返回 null 。
  21. pop():从这个 deque表示的堆栈中弹出一个元素。
  22. push(E e):将元素推送到由此 deque代表的堆栈(换句话说,在该 deque的头部),如果可以立即执行,而不违反容量限制,则抛出 IllegalStateException如果当前没有可用空间)。
  23. remove():检索并删除由此 deque表示的队列的头(换句话说,该 deque的第一个元素)。
  24. remove(Object o):删除第一个元素 e ,使 o.equals(e) ,如果这样一个元素存在于这个 deque,返回值为boolean。
  25. removeFirst():检索并删除此 deque的第一个元素。
  26. removeFirstOccurrence(Object o):删除第一个元素 e ,使 o.equals(e) ,如果这样一个元素存在于这个 deque,返回值为boolean。
  27. removeLast():检索并删除此 deque的最后一个元素。
  28. size():返回此 deque中的元素数。

实践


  
  1. import java.util.Queue;
  2. import java.util.concurrent.ConcurrentLinkedDeque;
  3. /**
  4. * 类描述
  5. *
  6. * @author: 12405
  7. * @date: 2020/3/20-22:43
  8. */
  9. public class MyQueue {
  10. public static void main(String[] args) {
  11. Queue<String> myQueue = new ConcurrentLinkedDeque<>();
  12. myQueue.offer( "null");
  13. myQueue.offer( "name");
  14. myQueue.offer( "Baldwin");
  15. myQueue.offer( "");
  16. System.out.println(myQueue);
  17. }
  18. }

  
  1. "C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\tools\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=55582:E:\tools\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;E:\Workspaces\IdeaProjects\DemoTest\out\production\DemoTest" cn.yzstu.queuetest.MyQueue
  2. [null, name, Baldwin, ]
  3. Process finished with exit code 0

5.DelayQueue队列

继承关系

底层

内部使用PriorityQueue实现

延时队列,在指定时间才能获取队列元素的功能,队列头元素是最接近过期的元素。

无界阻塞队列

DelayQueue<E extends Delayed>的队列元素需要实现Delayed接口。

队列元素需要实现getDelay(TimeUnit unit)方法和compareTo(Delayed o)方法, getDelay定义了剩余到期时间,compareTo方法定义了元素排序规则,注意,元素的排序规则影响了元素的获取顺序

元素不能为null

常用方法


  
  1. public boolean offer(E e)
  2. public void put (E e)
  3. public E poll ()
  4. public E take () throws InterruptedException
  5. public E peek ()
  6. public int size ()
  7. private E peekExpired ()
  8. public int drainTo (Collection<? super E> c)
  9. public void clear ()
  10. public int remainingCapacity ()
  11. public Object[] toArray ()
  12. public boolean remove (Object o)

实践

过期实践设置试验

继承与Delayed的DelayImpl类,DelayQueue中中只能储存此类对象


  
  1. import java.util.concurrent.Delayed;
  2. import java.util.concurrent.TimeUnit;
  3. /**
  4. * 类描述
  5. *
  6. * @author: 12405
  7. * @date: 2020/3/21-0:03
  8. */
  9. public class DelayImpl implements Delayed {
  10. private String name;
  11. private long outTime; //持续时间
  12. public DelayImpl(String name, long outTime) {
  13. this.name = name;
  14. //设置过期时间为outTime毫秒之后
  15. this.outTime = outTime+System.currentTimeMillis();
  16. }
  17. public String getName() {
  18. return name;
  19. }
  20. public void setName(String name) {
  21. this.name = name;
  22. }
  23. public long getOutTime() {
  24. return outTime;
  25. }
  26. public void setOutTime(long outTime) {
  27. this.outTime = outTime;
  28. }
  29. @Override
  30. public long getDelay(TimeUnit unit) {
  31. return unit.convert(outTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
  32. }
  33. @Override
  34. public int compareTo(Delayed o) {
  35. if (o == this)
  36. return 0;
  37. DelayImpl delayQueueModel = (DelayImpl)o;
  38. long time = (getDelay(TimeUnit.MILLISECONDS) - delayQueueModel.getDelay(TimeUnit.MILLISECONDS));
  39. return (time == 0) ? 0 : ((time < 0) ? - 1 : 1);
  40. }
  41. @Override
  42. public String toString() {
  43. return "DelayImpl{" +
  44. "name='" + name + '\'' +
  45. '}';
  46. }
  47. }

  
  1. import cn.yzstu.queuetest.delay.DelayImpl;
  2. import java.util.Queue;
  3. import java.util.concurrent.DelayQueue;
  4. import java.util.concurrent.Delayed;
  5. /**
  6. * 类描述
  7. *
  8. * @author: 12405
  9. * @date: 2020/3/20-22:43
  10. */
  11. public class MyQueue {
  12. public static void main(String[] args) throws InterruptedException {
  13. Queue<Delayed> myQueue = new DelayQueue<>();
  14. //设置两秒后过期
  15. DelayImpl delayed = new DelayImpl( "Baldwin", 2000);
  16. DelayImpl delayed1 = new DelayImpl( "Jack", 2000);
  17. myQueue.offer(delayed);
  18. myQueue.offer(delayed1);
  19. //第一次poll,过期时间未到,只能获取到null
  20. System.out.println(myQueue.poll());
  21. //等待3S,跳过过期时间
  22. Thread.sleep( 3* 1000);
  23. //重新尝试poll
  24. System.out.println(myQueue.poll());
  25. // LinkedBlockingDeque<String> myQueue = new LinkedBlockingDeque<>();
  26. // System.out.println(myQueue.remainingCapacity());
  27. }
  28. }

 


  
  1. "C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\tools\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=64710:E:\tools\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF -8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;E:\Workspaces\IdeaProjects\DemoTest\out\production\DemoTest" cn.yzstu.queuetest.MyQueue
  2. null
  3. DelayImpl{name= 'Baldwin'}
  4. Process finished with exit code 0

6.LinkedBlockingDeque队列

继承结构

底层

由链表构建

双向队列

相比于其他阻塞队列,LinkedBlockingDeque多了addFirst、addLast、peekFirst、peekLast等方法

可选容量,如果不设置,默认容量大小为Integer.MAX_VALUE

常用方法


  
  1. public void addFirst(E e)
  2. public void addLast (E e)
  3. public boolean offerFirst (E e)
  4. public boolean offerLast (E e)
  5. public void putFirst (E e) throws InterruptedException
  6. public void putLast (E e) throws InterruptedException
  7. public E removeFirst ()
  8. public E pollFirst ()
  9. public E peekFirst ()
  10. public E peekLast ()

实践

初始容量检测试验


  
  1. import java.util.concurrent.LinkedBlockingDeque;
  2. /**
  3. * 类描述
  4. *
  5. * @author: 12405
  6. * @date: 2020/3/20-22:43
  7. */
  8. public class MyQueue {
  9. public static void main(String[] args) throws InterruptedException {
  10. LinkedBlockingDeque<String> myQueue = new LinkedBlockingDeque<>();
  11. System.out.println(myQueue.remainingCapacity());
  12. }
  13. }

  
  1. "C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\tools\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=56432:E:\tools\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;E:\Workspaces\IdeaProjects\DemoTest\out\production\DemoTest" cn.yzstu.queuetest.MyQueue
  2. 2147483647
  3. Process finished with exit code 0

7.LinkedBlockingQueue队列

继承结构

底层

由链表结构组成的双向阻塞队列

LinkedBlockingQueue实现了BlockingQueue接口

添加元素和获取元素都有独立的锁,也就是说LinkedBlockingQueue是读写分离的,读写操作可以并行执行

LinkedBlockingQueue采用可重入锁(ReentrantLock)来保证在并发情况下的线程安全

常用方法


  
  1. public int size()
  2. public int remainingCapacity ()
  3. public void put (E e) throws InterruptedException
  4. public boolean offer (E e, long timeout, TimeUnit unit)
  5. public E take () throws InterruptedException
  6. public E poll (long timeout, TimeUnit unit) throws InterruptedException
  7. public E peek ()
  8. public boolean remove (Object o)
  9. public boolean contains (Object o)
  10. public Object[] toArray ()
  11. public void clear ()

8.LinkedTransferQueue队列

继承结构

底层

由链表结构组成的无界阻塞TransferQueue队列

相对于其他阻塞队列,LinkedTransferQueue多了tryTransfer和transfer方法

LinkedTransferQueue采用一种预占模式

使用CAS算法保证线程安全

元素不允许为null

size()需要遍历队列才能计算时间,并且不一定保证实时正确,因为遍历过程中元素数量可能会改变。

add(E e) ,向队尾插入元素,不阻塞,永远返回true

take(),尝试获取并删除队头元素,如果队列为空,则阻塞等待

常用方法


  
  1. public void put(E e)
  2. public boolean offer (E e, long timeout, TimeUnit unit)
  3. public boolean add (E e)
  4. public boolean tryTransfer (E e)
  5. public E take () throws InterruptedException
  6. public E poll (long timeout, TimeUnit unit) throws InterruptedException
  7. public E peek ()
  8. public boolean isEmpty ()
  9. public boolean hasWaitingConsumer ()
  10. public int size ()
  11. public int getWaitingConsumerCount ()
  12. public boolean remove (Object o)
  13. public boolean contains (Object o)
  14. public int remainingCapacity ()

实践

take()不阻塞实验


  
  1. import java.util.Queue;
  2. import java.util.concurrent.LinkedTransferQueue;
  3. /**
  4. * 类描述
  5. *
  6. * @author: 12405
  7. * @date: 2020/3/20-22:43
  8. */
  9. public class MyQueue {
  10. public static void main(String[] args) throws InterruptedException {
  11. Queue<String> myQueue = new LinkedTransferQueue<>();
  12. System.out.println(myQueue.add( "1"));
  13. System.out.println(myQueue.add( "2"));
  14. System.out.println(myQueue.add( "3"));
  15. System.out.println(myQueue.add( "4"));
  16. System.out.println(myQueue.add( "5"));
  17. System.out.println(myQueue.add( "6"));
  18. System.out.println(myQueue.add( "7"));
  19. System.out.println(myQueue);
  20. }
  21. }

  
  1. "C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\tools\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=65060:E:\tools\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;E:\Workspaces\IdeaProjects\DemoTest\out\production\DemoTest" cn.yzstu.queuetest.MyQueue
  2. true
  3. true
  4. true
  5. true
  6. true
  7. true
  8. true
  9. [1, 2, 3, 4, 5, 6, 7]
  10. Process finished with exit code 0

9.PriorityQueue队列

继承关系

底层

内部使用数组保存元素,平衡二叉堆实现排序

非线程安全

队列元素要么实现Comparable接口,要么构造器传入自定义的Comparator对象,使用这两个接口来实现排序

不允许包含null

默认初始容量为11

无容量限制,带有自动扩容机制

常用方法


  
  1. public boolean add(E e)
  2. public boolean offer (E e)
  3. public E peek ()
  4. public boolean remove (Object o)
  5. public boolean contains (Object o)
  6. public Object[] toArray ()

10.PriorityBlockingQueue队列

继承关系

底层

无界有序的阻塞队列

内部使用数组保存元素,平衡二叉堆实现排序

使用ReentrantLock和CAS保证并发访问

队列元素要么实现Comparable接口,要么构造器传入自定义的Comparator对象,使用这两个接口来实现排序

不允许null元素

从队列中获取到的元素是排好序的

初始默认容量为11

我容量限制,有自动扩容机制

常用方法


  
  1. public boolean add(E e)
  2. public boolean offer (E e)
  3. public void put (E e)
  4. public boolean offer (E e, long timeout, TimeUnit unit)
  5. public E poll ()
  6. public E take () throws InterruptedException
  7. public E peek ()
  8. public int size ()
  9. public int remainingCapacity ()
  10. public boolean remove (Object o)
  11. public boolean contains (Object o)
  12. public Object[] toArray ()
  13. public void clear ()

11.SynchronousQueue队列

继承关系

底层

不允许null元素

使用ReentrantLock和CAS来保证线程安全

默认为非公平策略,可在构造器中配置

阻塞队列,其中每个 put 必须等待一个 take,反之亦然。同步队列没有任何内部容量,甚至连一个队列的容量都没有

常用方法


  
  1. iterator() 永远返回空,因为里面没东西。
  2. peek() 永远返回null。
  3. put() 往 queue放进去一个element以后就一直wait直到有其他thread进来把这个element取走。
  4. offer() 往 queue里放一个element后立即返回,如果碰巧这个element被另一个thread取走了,offer方法返回 true,认为offer成功;否则返回 false
  5. offer( 2000, TimeUnit.SECONDS) 往 queue里放一个element但是等待指定的时间后才返回,返回的逻辑和offer()方法一样。
  6. take() 取出并且remove掉 queue里的element(认为是在 queue里的。。。),取不到东西他会一直等。
  7. poll() 取出并且remove掉 queue里的element(认为是在 queue里的。。。),只有到碰巧另外一个线程正在往 queue里offer数据或者put数据的时候,该方法才会取到东西。否则立即返回null。
  8. poll( 2000, TimeUnit.SECONDS) 等待指定的时间然后取出并且remove掉 queue里的element,其实就是再等其他的thread来往里塞。
  9. isEmpty()永远是 true
  10. remainingCapacity() 永远是 0
  11. remove()和removeAll() 永远是 false

声明一个SynchronousQueue有两种不同的方式,它们之间有着不太一样的行为。公平模式和非公平模式的区别:
  如果采用公平模式:SynchronousQueue会采用公平锁,并配合一个FIFO队列来阻塞多余的生产者和消费者,从而体系整体的公平策略;
  但如果是非公平模式(SynchronousQueue默认):SynchronousQueue采用非公平锁,同时配合一个LIFO(后进先出法 Last In First Out )队列来管理多余的生产者和消费者,而后一种模式,如果生产者和消费者的处理速度有差距,则很容易出现饥渴的情况,即可能有某些生产者或者是消费者的数据永远都得不到处理。

六、总结

Jdk提供了各式各样带有不同特性的队列,我们可以根据情况直接拿来使用,当然目前还有许多优秀的队列框架,如:ActiveMQ、RabbitMQ、RocketMQ(阿里)、kafka等,这些也是我们在项目中用到的比较多的,需要我们自己去判断需要使用哪一种队列,今天我们只说一下JDK中的队列,这些队列,你应该也算是稍微了解一点了吧?

七、后续

小丽:你讲的真详细,我明白了,但是我们不是应该在固戍下车么?现在好像已经到机场东了

Baldwin:我丢!你咋不提醒我

小丽:人家不是看你讲得那么认真,不忍心打断你么,这么晚了,反正也回不去了,恰好我带了身份证,咱们只能开一间房今晚在外面睡了

Baldwin:你SB么?咱就不能打车回去?车费AA不就行了

小丽:呵呵,那行吧,你个SB直男(小声)

Baldwin:啥?

小丽:没啥,我说祝你早日找到女朋友,你真是个好人

 


转载:https://blog.csdn.net/shouchenchuan5253/article/details/104994801
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场