并发编程-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接口的对象,其中的对象只能在其到期时才能从队列中取走.这种队列是有序的,即队头对象的延迟到期时间最长.注意:不能 ...
随机推荐
- 设置oracle密码不过期,修改用户密码
1. 查看用户名使用的profile select username,profile from dba_usersSELECT * FROM dba_profiles WHERE profile='D ...
- [AC自己主动机+可能性dp] hdu 3689 Infinite monkey theorem
意甲冠军: 给n快报,和m频率. 然后进入n字母出现的概率 然后给目标字符串str 然后问m概率倍的目标字符串是敲数量. 思维: AC自己主动机+可能性dp简单的问题. 首先建立trie图,然后就是状 ...
- 区别JS和DOM对象
<div> <button id="bt" onclick="ChangeColor()">Clike To Change Color& ...
- C# IDisposable接口的使用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- C#调用C/C++ DLL 参数传递和回调函数的总结
原文:C#调用C/C++ DLL 参数传递和回调函数的总结 Int型传入: Dll端: extern "C" __declspec(dllexport) int Add(int a ...
- WPF三维图形
原文:WPF三维图形 wpf 三维图形基础生成三维图形的基本思想是能得到一个物体的三维立体模型(model).由于我们的屏幕只有二维,因而我们定义了一个用于给物体拍照的照相机(Camera).拍到的照 ...
- Gralde 网络代理
Gralde 网络代理 Gradle在编译项目的时候,需要下载一些依赖.墙外的网络就需要设置代理了. 设置的方法,见文档: Accessing the web through a HTTP proxy ...
- Rails 最佳实践
在你业务简单的时候,让你简简单单用 ActiveRecord 模型. 复杂的时候,你可以用官方推荐的 Concerns. 更复杂的时候,可以通过 gem 和 API 来拆分. 极端复杂的时候,由于 R ...
- Delphi事件的广播
原文地址:Delphi事件的广播 转作者:MondaySoftware 明天就是五一节了,辛苦了好几个月,借此机会应该尽情放松一番.可是想到Blog好久没有写文章,似乎缺些什么似的.这几个月来在项目中 ...
- 支付宝RSA签名之Delphi实现
Delphi有个很大的问题就是,厂商的不作为(没有封装标准的Cipher类库),让大家自己造轮子. 今天的轮子就是RSA签名,由于Delphi没有封装Cipher类库,所以只的自己写了. 因为要在Fi ...