目录

集合Queue系列七并发安全Queue

【集合Queue系列七】并发安全Queue

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。

https://i-blog.csdnimg.cn/blog_migrate/5b7d56665d406fee3159289ac61fa974.jpeg#pic_center

  • 推荐: ,持续学习,不断总结,共同进步,活到老学到老
  • 导航
    • :全面总结 java 核心技术点,如集合,jvm,并发编程 redis,kafka,Spring,微服务,Netty 等
    • :罗列常用的开发工具,如 IDEA,Mac,Alfred,electerm,Git,typora,apifox 等
    • :详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
    • :总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
    • :总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂

非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨

博客目录

1.ConcurrentLinkedQueue 图解

https://i-blog.csdnimg.cn/blog_migrate/2337fa0dc9df0b297a2237fb98012b58.png

2.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);

继承与实现

ConcurrentLinkedQueue 类继承了哪些类

  • AbstractQueue 抽象类,具有队列的功能

ConcurrentLinkedQueue 类实现了哪些接口

  • Queue 接口,可作为队列使用

3.ConcurrentLinkedDeque 类

https://i-blog.csdnimg.cn/blog_migrate/159f990cba830e930377d12bfeae4f60.png

ConcurrentLinkedDeque原理图:

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

使用:

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

4.ArrayBlockingQueue 类

https://i-blog.csdnimg.cn/blog_migrate/4c6e97f768380955dd7343e2c17abaf8.png

ArrayBlockingQueuey原理:

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

使用:

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

BuildingBlockWithName buildingBlock1 = new BuildingBlockWithName("三角形", "A");
BuildingBlockWithName buildingBlock2 = new BuildingBlockWithName("四边形", "B");
ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(100, true);
arrayBlockingQueue.add(buildingBlock1);
arrayBlockingQueue.add(buildingBlock2);

5.LinkedBlockingQueue 类

https://i-blog.csdnimg.cn/blog_migrate/fb760f4dbe9c93550e8d2389903089b8.png

LinkedBlockingQueue原理:

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

LinkedBlockingQueue的应用场景:

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

LinkedBlockingQueue实现了哪些接口:

  • LinkedBlockingQueue 继承了 BlockingQueue 类,可作为阻塞队列使用
  • LinkedBlockingQueue 继承了 AbstractQueue 抽象类,具有队列的功能。
  • LinkedBlockingQueue 实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。

6.LinkedBlockingDeque 类

https://i-blog.csdnimg.cn/blog_migrate/010409f2d6b3bf0098173f1fa19f0efc.png

LinkedBlockingDeque原理:

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

LinkedBlockingDeque的应用场景:

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

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

LinkedBlockingDeque实现了哪些接口:

  • LinkedBlockingDeque 继承了 BlockingDeque 类,可作为阻塞队列使用
  • LinkedBlockingDeque 继承了 AbstractQueue 抽象类,具有队列的功能。
  • LinkedBlockingDeque 实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。

7.PriorityBlockingQueue 类

https://i-blog.csdnimg.cn/blog_migrate/3fd55b861cd36ff444637f35d2f03464.png

PriorityBlockQueue的原理:

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

PriorityBlockQueue实现了哪些接口:

  • LinkedBlockingQueue 继承了 BlockingQueue 接口,可作为阻塞队列使用
  • LinkedBlockingQueue 继承了 AbstractQueue 抽象类,具有队列的功能。
  • LinkedBlockingQueue 实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。

觉得有用的话点个赞 👍🏻 呗。

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

https://i-blog.csdnimg.cn/blog_migrate/101469850485989da7dda6f53e80e19d.gif#pic_center