直接上代码

  class LinkedBlockingDequeDemo {
// 循环是否结束的开关
private static volatile boolean flag1 = true;
private static volatile boolean flag2 = true;
// 生成者生产的产品
private static AtomicInteger atomicInteger = new AtomicInteger(1);
//二个 双端阻塞队列
private LinkedBlockingDeque linkedBlockingDeque1;
private LinkedBlockingDeque linkedBlockingDeque2; public LinkedBlockingDequeDemo(LinkedBlockingDeque linkedBlockingDeque1, LinkedBlockingDeque linkedBlockingDeque2) {
this.linkedBlockingDeque1 = linkedBlockingDeque1;
this.linkedBlockingDeque2 = linkedBlockingDeque2;
System.out.println(linkedBlockingDeque1.getClass().getName());
System.out.println(linkedBlockingDeque2.getClass().getName());
} // 生产者
public void producer() throws InterruptedException {
String data = "";
while (flag1) {
data = atomicInteger.getAndIncrement() + "";//这是产品
//TimeUnit.SECONDS.sleep(1);// 1秒生成一个产品
if (Integer.valueOf(data) <= 10) {
//存到 linkedBlockingDeque1 队列中
linkedBlockingDeque1.put(data + "队列1");
System.out.println(Thread.currentThread().getName() + "添加元素到 阻塞队列 linkedBlockingDeque1,成功,元素为: " + data + "队列1");
} else {
//存到 linkedBlockingDeque2 队列中
linkedBlockingDeque2.put(data + "队列2");
System.out.println(Thread.currentThread().getName() + "添加元素到 阻塞队列 linkedBlockingDeque2,成功,元素为: " + data + "队列2");
}
}
} // 消费者
public void consumer1() throws InterruptedException {
while (flag2) {
try {
TimeUnit.MILLISECONDS.sleep(3);
if (!linkedBlockingDeque1.isEmpty()) {
// 自己的队列不为空, 就从自己的队列中取数据消费, 从头开始消费数据
System.out.println(Thread.currentThread().getName() + "从自己队列 Deque1中 的头部消费了一个产品:" + linkedBlockingDeque1.takeFirst());
} else if (!linkedBlockingDeque2.isEmpty()) {
// 如果 另一个队列不为空, 就从他的尾开始消费数据
System.out.println(Thread.currentThread().getName() + "从别人队列 Deque2中 的尾部消费了一个产品:" + linkedBlockingDeque2.takeLast());
} else {
flag2 = false;//这里结束消费
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("------------------------------------------");
}
} public void consumer2() throws InterruptedException {
while (flag2) {
try {
TimeUnit.MILLISECONDS.sleep(3);
if (!linkedBlockingDeque2.isEmpty()) {
// 自己的队列不为空, 就从自己的队列中取数据消费, 从头开始消费数据
System.out.println(Thread.currentThread().getName() + "从自己队列 Deque2中 的头部消费了一个产品:" + linkedBlockingDeque2.takeFirst());
} else if (!linkedBlockingDeque1.isEmpty()) {
// 如果 另一个队列不为空, 就从他的尾开始消费数据
System.out.println(Thread.currentThread().getName() + "从别人队列 Deque1中 的尾部消费了一个产品:" + linkedBlockingDeque1.takeLast());
} else {
flag2 = false;//这里结束消费
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("------------------------------------------");
}
} // 停止生产的方法
public void stop() {
this.flag1 = false;
} public static void main(String[] args) throws InterruptedException {
//工作窃取代码演示: 什么是工作窃取? 在生产者和消费者模型中,
// 每个消费者都对应一个阻塞队列(LinkedBlockingDeque),当消费者当前的队列中的任务消费完了后, 不会就此结束,
// 他会从另一个队列中获取对应的任务来进行消费,
// 这就是 LinkedBlockingDeque的好处,因为他是双端队列,可以从头和尾 来获取元素 /**
*
* 看到的效果就是: 消费者线程1, 从自己的队列Deque1 中, 从头部开始消费1-10, 之后,开始从 别人的队列Deque2中消费产品了
*
* 这里让生产者 1毫秒之后停止生产,然后消费者开始消费
*/
LinkedBlockingDeque<String> linkedBlockingDeque1 = new LinkedBlockingDeque<>();
LinkedBlockingDeque<String> linkedBlockingDeque2 = new LinkedBlockingDeque<>();
LinkedBlockingDequeDemo linkedBlockingDequeDemo = new LinkedBlockingDequeDemo(linkedBlockingDeque1, linkedBlockingDeque2); new Thread(() -> {
try {
linkedBlockingDequeDemo.producer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "生产者线程").start(); new Thread(() -> {
try {
linkedBlockingDequeDemo.consumer1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "消费者线程1").start(); new Thread(() -> {
try {
linkedBlockingDequeDemo.consumer2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "消费者线程2").start(); TimeUnit.MILLISECONDS.sleep(1);
linkedBlockingDequeDemo.stop();
}
}

运行结果 : 可以看到 线程1,在自己的阻塞队列中消费完之后, 并没有结束,从别人的队列中来 获取任务来执行







JUC 并发编程--10, 阻塞队列之--LinkedBlockingDeque 工作窃取, 代码演示的更多相关文章

  1. JUC 并发编程--07 阻塞队列版本的 生产者消费者(不使用synchronized和 lock),也有一些疑惑,最终解惑

    直接上代码: 前提是你已经 熟悉了原子类,volatile,和阻塞队列 public class JucPCdemo03 { /** * 阻塞队列的应用: 这里实现的生产者消费者,生产一个消费一个 * ...

  2. JUC 并发编程--09, 阻塞队列: DelayQueue, PriorityBlockingQueue ,SynchronousQueue, 定时任务线程池: ScheduledThreadPoolExecutor

    先看DelayQueue 这个是用优先级队列实现的无界限的延迟队列,直接上代码: /** * 这个是 {@link DelayQueue} 延时队列 的验证使用类 */ class MyDelayed ...

  3. JUC 并发编程--06, 阻塞队列(7种), 阻塞等待 api的 代码验证

    这些队列的 api ,就是添加队列,出队列,检测对首元素, 由于 add()--remove(), offer()--poll(),太简单这里不做验证, 只验证后二组api: 阻塞等待( put()- ...

  4. Java并发编程:阻塞队列(转载)

    Java并发编程:阻塞队列 在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList), ...

  5. 【转】Java并发编程:阻塞队列

    在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList),这些工具都为我们编写多线程程 ...

  6. 12、Java并发编程:阻塞队列

    Java并发编程:阻塞队列 在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList), ...

  7. (转)Java并发编程:阻塞队列

    Java并发编程:阻塞队列 在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList), ...

  8. java并发编程学习: 阻塞队列 使用 及 实现原理

    队列(Queue)与栈(Stack)是数据结构中的二种常用结构,队列的特点是先进先出(First In First Out),而Stack是先进后出(First In Last Out),说得通俗点: ...

  9. java并发编程:阻塞队列

    一.几种主要的阻塞队列 自从Java 1.5之后,在java.util.concurrent包下提供了若干个阻塞队列,主要有以下几个: ArrayBlockingQueue:基于数组实现的一个阻塞队列 ...

随机推荐

  1. Google Hacking的用法

    目录 Google Hacking 基本搜索 高级搜索 Index of inurl Google Hacking Google Hacking 是利用谷歌搜索的强大,来在浩瀚的互联网中搜索到我们需要 ...

  2. 5.PHP与Web页面交互

    PHP与Web页面交互 PHP中提供了两种与Web页面交互的方法,一种是通过Web表单提交数据,另一种是通过URL参数传递. 表单提交用户名字和密码: <form name "form ...

  3. HTTP1.0,1.1,2.0,HTTPS

    HTTP1.0/1.1/2.0/HTTPS HTTP(超文本传输协议)是互联网上应用最为广泛的一种网络协议.所有的WWW文件都必须遵守这个标准.设计HTTP最初的目的是为了提供一种发布和接收HTML页 ...

  4. React-列表 & Key

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...

  5. ThinkPHP5查询-select与find理解

    出现问题 在tp5框架中判断select查询结果是否为空时,无论查询条件是否满足,判断查询结果都不为空 解析问题 select查询的是多条数据,若查询数据为空,则返回一个空的二维数组 array(ar ...

  6. Django(3)pycharm创建项目

    创建项目 我们创建django项目有两种方式,命令行方式和使用pycharm工具创建,本文就介绍常用的pycharm工具创建   首先点击django,输入项目的名称,选择创建好的虚拟环境,最后点击c ...

  7. Educational Codeforces Round 96 (Rated for Div. 2)

    A. Number of Apartments 题意:求方程的解 思路:直接模拟就行 代码: #include<iostream> #include<cstdio> #incl ...

  8. Zoho创始人斯瑞达.温布获评“年度最佳CEO”

    近日,权威研究和咨询机构Constellation Research公布了一系列奖项,Zoho创始人斯瑞达.温布获评"年度最佳CEO"(The Best Enterprise CE ...

  9. CSS3 变形

    目录 Transform Transform与坐标系统 transform-origin transform-style 二维旋转 旋转 rotate 平移 translate translateX ...

  10. Linux 用 ps 與 top 指令找出最耗費 CPU 與記憶體資源的程式最占cpu的进程

    Linux 用 ps 與 top 指令找出最耗費 CPU 與記憶體資源的程式 2016/12/220 Comments  ######### ps -eo pid,ppid,%mem,%cpu,cmd ...