并发编程-concurrent指南-阻塞双端队列-链阻塞双端队列LinkedBlockingDeque
LinkedBlockingDeque是双向链表实现的阻塞队列。该阻塞队列同时支持FIFO和FILO两种操作方式,即可以从队列的头和尾同时操作(插入/删除);
在不能够插入元素时,它将阻塞住试图插入元素的线程;在不能够抽取元素时,它将阻塞住试图抽取的线程。;
LinkedBlockingDeque还是可选容量的,防止过度膨胀,默认等于Integer.MAX_VALUE。;
LinkedBlockingDueue没有进行读写锁的分离,因此同一时间只能有一个线程对其操作,因此在高并发应用中,它的性能要远远低于LinkedBlockingQueue。
具体代码:
import java.util.concurrent.LinkedBlockingDeque;
public class Main {
public static void main(String[] args) {
//给个3的队列
LinkedBlockingDeque<Integer> linkedBlockingDeque = new LinkedBlockingDeque<Integer>(3);
//生产者
Producer firstProducer = new FirstProducer(linkedBlockingDeque);//头部插入
Producer lastProducer = new LastProducer(linkedBlockingDeque);//尾部插入
firstProducer.start();
// lastProducer.start();
//消费者
Consumer firstConsumer = new FirstConsumer(linkedBlockingDeque);//头部获取
Consumer lastConsumer = new LastConsumer(linkedBlockingDeque);//尾部获取
// firstConsumer.start();
lastConsumer.start();
}
}
import java.util.Random;
import java.util.concurrent.LinkedBlockingDeque; /**
* 生产者
*/
public abstract class Producer extends Thread{
protected LinkedBlockingDeque<Integer> linkedBlockingDeque;
public Producer(LinkedBlockingDeque<Integer> linkedBlockingDeque){
this.linkedBlockingDeque = linkedBlockingDeque;
} @Override
public void run() {
while(true){
int random = new Random().nextInt(1000);
try {
this.putQueue(random);//插入数据
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public abstract void putQueue(int random) throws InterruptedException;
}
import java.util.concurrent.LinkedBlockingDeque; /**
* 头部插入
*/
public class FirstProducer extends Producer{
public FirstProducer(LinkedBlockingDeque<Integer> linkedBlockingDeque) {
super(linkedBlockingDeque);
} @Override
public void putQueue(int random) throws InterruptedException {
System.out.println("头部生产产品:"+random);
super.linkedBlockingDeque.putFirst(random);
System.out.println("头部生产产品:"+random+",结束");
}
}
import java.util.concurrent.LinkedBlockingDeque; /**
* 尾部插入:默认是尾部插入
*/
public class LastProducer extends Producer{
public LastProducer(LinkedBlockingDeque<Integer> linkedBlockingDeque) {
super(linkedBlockingDeque);
} @Override
public void putQueue(int random) throws InterruptedException {
super.linkedBlockingDeque.putLast(random);
}
}
import java.util.concurrent.LinkedBlockingDeque; /**
* 消费者
*/
public abstract class Consumer extends Thread{
protected LinkedBlockingDeque<Integer> linkedBlockingDeque;
public Consumer(LinkedBlockingDeque<Integer> linkedBlockingDeque){
this.linkedBlockingDeque = linkedBlockingDeque;
} @Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("------------------------------------");
while(true){
try {
System.out.println("尾部等待3秒开始获取产品");
Thread.sleep(3000);
this.takeQueue();//获取数据
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public abstract void takeQueue() throws InterruptedException;
}
import java.util.concurrent.LinkedBlockingDeque; /**
* 头部获取
*/
public class FirstConsumer extends Consumer{
public FirstConsumer(LinkedBlockingDeque<Integer> linkedBlockingDeque) {
super(linkedBlockingDeque);
} @Override
public void takeQueue() throws InterruptedException {
System.out.println("头部获取产品开始");
Integer random = super.linkedBlockingDeque.takeFirst();
System.out.println("头部获取产品:"+random+",结束");
}
}
import java.util.concurrent.LinkedBlockingDeque; /**
* 尾部获取
*/
public class LastConsumer extends Consumer{
public LastConsumer(LinkedBlockingDeque<Integer> linkedBlockingDeque) {
super(linkedBlockingDeque);
} @Override
public void takeQueue() throws InterruptedException {
Integer random = super.linkedBlockingDeque.takeLast();
System.out.println("尾部获取产品:"+random+",结束");
}
}
源码地址:https://github.com/qjm201000/concurrent_linkedBlockingDeque.git
并发编程-concurrent指南-阻塞双端队列-链阻塞双端队列LinkedBlockingDeque的更多相关文章
- 并发编程-concurrent指南-阻塞双端队列BlockingDeque
java.util.concurrent 包里的 BlockingDeque 接口表示一个线程安放入和提取实例的双端队列. BlockingDeque 类是一个双端队列,在不能够插入元素时,它将阻塞住 ...
- 并发编程-concurrent指南-阻塞队列-链表阻塞队列LinkedBlockingQueue
LinkedBlockingQueue是一个基于链表的阻塞队列. 由于LinkedBlockingQueue实现是线程安全的,实现了先进先出等特性,是作为生产者消费者的首选. LinkedBlocki ...
- 并发编程-concurrent指南-阻塞队列BlockingQueue
阻塞队列BlockingQueue,java.util.concurrent下的BlockingQueue接口表示一个线程放入和提取实例的队列. 适用场景: BlockingQueue通常用于一个线程 ...
- 深入理解java:2.3.4. 并发编程concurrent包 之容器ConcurrentLinkedQueue(非阻塞的并发队列---循环CAS)
1. 引言 在并发编程中我们有时候需要使用线程安全的队列. 如果我们要实现一个线程安全的队列有两种实现方式:一种是使用阻塞算法,另一种是使用非阻塞算法. 使用阻塞算法的队列可以用一个锁(入队和出 ...
- 并发编程-concurrent指南-原子操作类-AtomicInteger
在java并发编程中,会出现++,--等操作,但是这些不是原子性操作,这在线程安全上面就会出现相应的问题.因此java提供了相应类的原子性操作类. 1.AtomicInteger
- 并发编程-concurrent指南-阻塞队列-同步队列SynchronousQueue
SynchronousQueue:同步Queue,属于线程安全的BlockingQueue的一种,此队列设计的理念类似于"单工模式",对于每个put/offer操作,必须等待一个t ...
- 并发编程-concurrent指南-阻塞队列-优先级的阻塞队列PriorityBlockingQueue
PriorityBlockingQueue是一个支持优先级的无界阻塞队列. 它使用了和类 java.util.PriorityQueue 一样的排序规则.你无法向这个队列中插入 null 值. 所有插 ...
- 并发编程-concurrent指南-阻塞队列-数组阻塞队列ArrayBlockingQueue
ArrayBlockingQueue类是实现了BlockingQueue. ArrayBlockingQueue是一个有界的阻塞队列,其内部实现是将对象放在一个数组中. 放入元素方法: (1) add ...
- 并发编程-concurrent指南-阻塞队列-延迟队列DelayQueue
DelayQueue是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走.这种队列是有序的,即队头对象的延迟到期时间最长.注意:不能 ...
随机推荐
- 关于禅道提示未安装VC++环境的问题(做个记录)
明明安装了VC++环境,总是提示未安装,这个问题有可能是你的mysql或其他服务开启影响的,关闭服务就可以了! 我这边是这个问题,把mysql和其他一些服务停止就好了.
- multi-node和generic-pool两大利器
1.multi-node node只能单进程,单cpu工作,而multi-node则可以让node在多进程下共享内存的工作,实现机制是依靠child_process的sendmsg做到的.想要了解具体 ...
- AngularJS ng-if使用
示例中,根据ng-if指令显示不同任务状态,以及判断任务是否可以操作 <div ng-app="NgifDemoApp" ng-controller="NgifDe ...
- Win8 Metro(C#)数字图像处理--2.48Canny边缘检测算法
原文:Win8 Metro(C#)数字图像处理--2.48Canny边缘检测算法 [算法说明] Canny边缘检测算法可以分为4步:高斯滤波器平滑处理.梯度计算.非极大值抑制.双阈值边缘检 测和 ...
- xgboost参数及调参
常规参数General Parameters booster[default=gbtree]:选择基分类器,可以是:gbtree,gblinear或者dart.gbtree和draf基于树模型,而gb ...
- 21 步助你成为成功的 Web 开发者(激情不是被动的:它是一种对行动起来的追求)
随着 Web 开发产业的爆发式发展,许多人会问这样的问题:我如何才能成为一名 Web 开发者?我认为这是一个错误的提问.问题应该是:我如何才能成为一名成功的 Web 开发者? 能提出这样的问题很重要, ...
- BSTR使用误区以及隐藏的内存破坏和内存泄漏
BSTR使用误区以及隐藏的内存破坏和内存泄漏 作者:magictong 简介 BSTR的数据结构是什么样子并不是本文讨论的问题,但是却是本文的基础.在解决COM的跨平台编程的问题时,需要定义一种通用的 ...
- android核心系列--2,关于任务栈(task)
一,任务 任务是由界面组件组成的一个栈,这些界面组件可以来自多个进程,多个应用,为共同完成一项任务而存在,比如写邮件时会用到邮件应用和联系人应用中的界面组件,这些界面组件在同一个任务中运行. 二,界面 ...
- 【Linux】Linux 环境下splite以及一些正则使用
由于在windows下,遍历目录,想查找满足条件的文件: dir /s > ..\fileresult.txt 结果得到的文件过大,999多MB的txt: split -b 10k date.f ...
- windows 消息列表
private const UInt32 WM_ACTIVATE = 0x0006; private const UInt32 WM_ACTIVATEAPP = 0x001C; private con ...