队列Queue-07
【摘要】 1.ConcurrentLinkedQueue 图解 2.ConcurrentLinkedQueue 原理ConcurrentLinked 是由链表结构组成的线程安全的先进先出无界队列。当多线程要共享访问集合时,ConcurrentLinkedQueue 是一个比较好的选择。不允许插入 null 元素支持非阻塞地访问并发安全的队列,不会抛出 ConcurrentModifiationExc...
1.ConcurrentLinkedQueue 图解
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 类
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 类
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 类
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 类
LinkedBlockingDeque原理:
- 由链 LinkedBlockingDeque = 阻塞队列+链表+双端访问
- 线程安全。
- 多线程同时入队时,因多了一端访问入口,所以减少了一半的竞争。
- 默认容量大小为 Integer.MAX_VALUE。可指定容量大小。
LinkedBlockingDeque的应用场景:
LinkedBlockingDeque 可以用在“工作窃取“模式中。
工作窃取算法
:某个线程比较空闲,从其他线程的工作队列中的队尾窃取任务来帮忙执行。
LinkedBlockingDeque实现了哪些接口:
- LinkedBlockingDeque 继承了 BlockingDeque 类,可作为阻塞队列使用
- LinkedBlockingDeque 继承了 AbstractQueue 抽象类,具有队列的功能。
- LinkedBlockingDeque 实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。
7.PriorityBlockingQueue 类
PriorityBlockQueue的原理:
- PriorityBlockQueue = PriorityQueue + BlockingQueue
- 之前我们也讲到了 PriorityQueue 的原理,支持对元素排序。
- 元素默认自然排序。
- 可以自定义 CompareTo()方法来指定元素排序规则。
- 可以通过构造函数构造参数 Comparator 来对元素进行排序。
PriorityBlockQueue实现了哪些接口:
- LinkedBlockingQueue 继承了 BlockingQueue 接口,可作为阻塞队列使用
- LinkedBlockingQueue 继承了 AbstractQueue 抽象类,具有队列的功能。
- LinkedBlockingQueue 实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)