生产者消费者代码学习,Producer_Consuner
使用BlockingQuery实现生产者者消费者:考虑并发,解耦。
生产者消费者模式是面向过程的设计模式。
生产者制造数据 ------》 生产者把数据放入缓冲区 -------》 消费者把数据取出缓冲区 --------》相当于消费者处理数据
BlockingQuery学习
支持两个附加操作的 Queue,这两个操作是:获取元素时等待队列变为非空,以及存储元素时等待空间变得可用。
BlockingQueue 方法以四种形式出现,对于不能立即满足但可能在将来某一时刻可以满足的操作,这四种形式的处理方式不同:第一种是抛出一个异常,第二种是返回一个特殊值(null 或 false,具体取决于操作),第三种是在操作可以成功前,无限期地阻塞当前线程,第四种是在放弃前只在给定的最大时间限制内阻塞。下表中总结了这些方法:
| 抛出异常 | 特殊值 | 阻塞 | 超时 | |
| 插入 | add(e) |
offer(e) |
put(e) |
offer(e, time, unit) |
| 移除 | remove() |
poll() |
take() |
poll(time, unit) |
| 检查 | element() |
peek() |
不可用 | 不可用 |
BlockingQueue 不接受 null 元素。试图 add、put 或 offer 一个 null 元素时,某些实现会抛出 NullPointerException。null 被用作指示 poll 操作失败的警戒值。
BlockingQueue 可以是限定容量的。它在任意给定时间都可以有一个 remainingCapacity,超出此容量,便无法无阻塞地 put 附加元素。没有任何内部容量约束的 BlockingQueue 总是报告 Integer.MAX_VALUE 的剩余容量。
BlockingQueue 实现主要用于生产者-使用者队列,但它另外还支持 Collection 接口。因此,举例来说,使用 remove(x) 从队列中移除任意一个元素是有可能的。然而,这种操作通常不 会有效执行,只能有计划地偶尔使用,比如在取消排队信息时。
BlockingQueue 实现是线程安全的。所有排队方法都可以使用内部锁或其他形式的并发控制来自动达到它们的目的。然而,大量的 Collection 操作(addAll、containsAll、retainAll 和 removeAll)没有 必要自动执行,除非在实现中特别说明。因此,举例来说,在只添加了 c 中的一些元素后,addAll(c) 有可能失败(抛出一个异常)。
BlockingQueue 实质上不 支持使用任何一种“close”或“shutdown”操作来指示不再添加任何项。这种功能的需求和使用有依赖于实现的倾向。例如,一种常用的策略是:对于生产者,插入特殊的 end-of-stream 或 poison 对象,并根据使用者获取这些对象的时间来对它们进行解释。
生产者code
package com.liruilong.concurrent.Producer_Consuner; import javax.swing.text.StyledEditorKit;
import java.util.concurrent.BlockingQueue; /**
* @Description : 生产者
* @Author: Liruilong
* @Date: 2019/8/22 7:24
*/
public class Producer implements Runnable{ private find BlockingQueue<String> queue; public Producer(BlockingQueue<String> queue){
this.queue = queue;
}
@Override
public void run() {
try {
String temp = "产品:"+Thread.currentThread().getName();
System.out.println("生产产品: "+Thread.currentThread().getName());
queue.put(temp); //队列已满,阻塞队列。
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
消费者code
package com.liruilong.concurrent.Producer_Consuner; import java.util.concurrent.BlockingQueue; /**
* @Description : 消费者
* @Author: Liruilong
* @Date: 2019/8/22 7:56
*/
public class Consumer implements Runnable{
private find BlockingQueue<String> queue; public Consumer(BlockingQueue<String> queue) { this.queue = queue;
}
@Override
public void run() {
try {
// 队列为空,阻塞当前线程
String temp = queue.take();
System.out.println("消费产品:" + temp);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
测试
package com.liruilong.concurrent.Producer_Consuner; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; /**
* @Description : 生产者消费者测试
* @Author: Liruilong
* @Date: 2019/8/22 8:01
*/
public class Test {
public static void main(String[] args) {
// 一个基于已链接节点的、任选范围的阻塞双端队列。
BlockingQueue<String> query = new LinkedBlockingQueue<>(2);
Consumer consumer = new Consumer(query);
Producer producer = new Producer(query);
for (int i = 0; i < 5; i ++){
new Thread(producer,"Producer" + (i + 1)).start(); new Thread(consumer, "Consumer" + (i + 1)).start();
}
}
}
jdk1.6API中关于生产者消费者模式书写:
package com.liruilong.concurrent.Producer_Consuner; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque; /**
* @Description :
* @Author: Liruilong
* @Date: 2019/8/22 8:43
*/
public class Code { public static void main(String[] args) { new Code().new Setup().main();
} class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while(true) {
queue.put(produce());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
Object produce() {
System.out.println("生产商品啦!");
return "商品";
}
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while(true) {
consume(queue.take());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
void consume(Object x) { System.out.println("商品被消费掉啦!");
}
}
class Setup {
void main() {
BlockingQueue q = new LinkedBlockingDeque(4);
// 生产者
Producer p = new Producer(q);
// 消费者
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q); Thread threadProducer = new Thread(p);
while ( !threadProducer.isInterrupted()) {
// 生产商品
threadProducer.start();
// 消费商品
new Thread(c1).start();
new Thread(c2).start();
threadProducer.interrupt();
}
}
} }
生产者消费者代码学习,Producer_Consuner的更多相关文章
- Linux 进程间通信(包含一个经典的生产者消费者实例代码)
前言:编写多进程程序时,有时不可避免的需要在多个进程之间传递数据,我们知道,进程的用户的地址空间是独立,父进程中对数据的修改并不会反映到子进程中,但内核是共享的,大多数进程间通信方式都是在内核中建立一 ...
- 基于kafka_2.11-2.1.0实现的生产者和消费者代码样例
1.搭建部署好zookeeper集群和kafka集群,这里省略. 启动zk: bin/zkServer.sh start conf/zoo.cfg. 验证zk是否启动成功: bin/zkServer. ...
- java线程之多个生产者消费者
温故一下上一节所学习的生产者消费者代码: 两个线程时: 通过标志位flag的if判断和同步函数互斥较好解决两个线程,一个生产者.一个消费者交替执行的功能 类名:ProducterConsumerDem ...
- java 多线程并发系列之 生产者消费者模式的两种实现
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据 ...
- Java设计模式—生产者消费者模式(阻塞队列实现)
生产者消费者模式是并发.多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据.这篇文章我们来看看什么是生产者消费者模式,这个问 ...
- Linux多线程实践(5) --Posix信号量与互斥量解决生产者消费者问题
Posix信号量 Posix 信号量 有名信号量 无名信号量 sem_open sem_init sem_close sem_destroy sem_unlink sem_wait sem_post ...
- 多线程-生产者消费者(synchronized同步)
正解博客:https://blog.csdn.net/u011863767/article/details/59731447 永远在循环(loop)里调用 wait 和 notify,不是在 If 语 ...
- Java 学习笔记 使用并发包ReentrantLock简化生产者消费者模式代码
说明 ReentrantLock是java官方的一个线程锁类,ReentarntLock实现了Lock的接口 我们只需要使用这个,就可以不用使用synchronized同步关键字以及对应的notify ...
- 生产者与消费者 代码实现 java
首先,我利用忙测试写出了第一次版本的代码 package How; //自写代码 缺陷 无法完全实现pv操作线程处于忙测试状态 public class bin_1_1 { public static ...
随机推荐
- H3C配置BPDU的生成和传递
- js求1到任意数之间的所有质数
何为质数: 只能被1 和 自身 整除的数; 方法: 利用js中求模, 看是否有余数. ---> 3%2 = 1; 5%2 = 3......... 代码如下: function test (n) ...
- linux内核指针和错误值
很多内部内核函数返回一个指针值给调用者. 许多这些函数也可能失败. 大部分情况, 失 败由返回一个 NULL 指针值来指示. 这个技术是能用的, 但是它不能通知问题的确切特性. 一些接口确实需要返回一 ...
- 2018-11-9-win2d-CanvasCommandList-使用方法
title author date CreateTime categories win2d CanvasCommandList 使用方法 lindexi 2018-11-9 20:8:4 +0800 ...
- vue 插件大全
UI组件 element - 饿了么出品的Vue2的web UI工具套件 Vux - 基于Vue和WeUI的组件库 mint-ui - Vue 2的移动UI元素 iview - 基于 Vuejs 的开 ...
- koa2入门--09.art-template高速模板引擎的使用
首先在项目文件夹下使用 cmd,输入:npm install --save art-template koa-template art-template语法参考:http://aui.github.i ...
- 【36.11%】【codeforces 725C】Hidden Word
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- boostrap-非常好用但是容易让人忽略的地方【4】:Font Awesome
font-awesome基本用法 官方代码传送门 font-awesome在bootstrap中的特殊用法(这个才是重点) 要点归纳1(官方) 官方代码传送门 要点归纳2(我的) <a href ...
- 创意app1
app名称: 与我相似的人 app目的: 旨在通过云匹配,搜索到与自己类似爱好或者性格的人用户相似的内容:衣服品牌鞋子手机笔记本键盘鼠标相机刮胡刀自行车工作 说明: 现有的格局 百度贴吧是面向多 ...
- Python10_代码规范和可读性
养成好的编程习惯和方法对提升代码可读性至关重要. 1.类.模块.包:不要用下划线,命名要简短 2.类:命名最好以大写开头 3.模块.包:用小写单词 4.变量.函数.方法:可以用下划线提高可读性,尽量都 ...