多生产者多消费者(第二种方式2.1)基于BlockingQueue
public class Producer implements Runnable {
//静态变量只初始化一次
private static AtomicInteger count = new AtomicInteger();
private volatile boolean isRunning = true;
private BlockingQueue<String> queue;
private String name;
public Producer(BlockingQueue<String> queue, String name) {
this.queue = queue;
this.name = name;
}
public void run() {
String data = null;
Random r = new Random();
System.out.println("启动" + name);
try {
while (isRunning) {
Thread.sleep(r.nextInt());
data = "data:" + count.incrementAndGet();
System.out.println(name + "生产数据:" + data);
queue.put(data);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + "退出!");
}
public void stop() {
isRunning = false;
}
}
public class Consumer implements Runnable {
private volatile boolean isRunning = true;
private BlockingQueue<String> queue;
private String name;
public Consumer(BlockingQueue<String> queue, String name) {
this.queue = queue;
this.name = name;
}
public void run() {
System.out.println("启动" + name);
try {
while (isRunning) {
String data = queue.take();
System.out.println(name + "消费数据:" + data);
Thread.sleep();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + "退出!");
}
public void stop() {
isRunning = false;
}
}
public class Client {
public static void main(String[] args) throws InterruptedException {
// 声明一个容量为10的缓存队列
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
Producer producer1 = new Producer(queue , "【生产者一】");
Producer producer2 = new Producer(queue ,"【生产者二】");
Consumer consumer1 = new Consumer(queue ,"【消费者一】");
// 借助Executors
ExecutorService service = Executors.newCachedThreadPool();
// 启动线程
service.execute(producer1);
service.execute(producer2);
service.execute(consumer1);
// 执行7s
Thread.sleep( * );
producer1.stop();
producer2.stop();
service.shutdown();
}
}
队列的操作:
offer 是向队列尾部添加元素,返回true或者false
poll 是从队列头部取数据,如果没有取到返回null
offer和poll都不会阻塞当前线程
阻塞操作
put 往队列当中中放入数据
take 从队列当中取数据
多生产者多消费者(第二种方式2.1)基于BlockingQueue的更多相关文章
- Java创建线程的第二种方式:实现runable接口
/*需求:简单的卖票程序多个窗口买票 创建线程的第二种方式:实现runable接口 *//*步骤1.定义类实现Runable接口2.覆盖Runable接口中的run方法 将线程要运行的代码存放在 ...
- JS定义函数的2种方式以及区别简述(为什么推荐第二种方式)
无意中看到了阮一峰大神多年前的一篇博客: 12种不宜使用的Javascript语法 看到第9条的时候受到了启发,感觉之前没怎么理解清楚的一些问题好像突然就清晰了,如下图 可能光这样看,有些小伙 ...
- Spring整合Struts2框架的第二种方式(Action由Spring框架来创建)(推荐大家来使用的)
1. spring整合struts的基本操作见我的博文:https://www.cnblogs.com/wyhluckdog/p/10140588.html,这里面将spring与struts2框架整 ...
- 创建线程的第二种方式------实现Runnable接口的方式
package cn.itcast.demo16.Demo07.Runnable;/** * @author newcityman * @date 2019/7/22 - 23:17 */public ...
- 多线程-创建线程第二种方式-实现Runnable接口-细节和好处
1 package multithread2; 2 3 /* 4 * 创建线程的第一种方法:继承Thread类 5 * 6 * 创建线程的第二种方式:实现Runnable接口 7 * 8 * 1,定义 ...
- Thread类的常用方法_sleep和创建多线程程序的第二种方式_实现Runnable接口
sleep方法是在Thread类中的一个静态方法,当一个线程调用了sleep方法,被调用的那个线程就会暂时的让出指定时间的CPU执行权,在这段时间也不会参与CPU的调度,当时间到了之后,就会重新回到就 ...
- throws关键字_异常处理的第一种方式(交给别人处理)和try_catch_异常处理的第二种方式(自己处理)
throws关键字:异常处理的第一种方式,交给别人处理 作用: 当方法内部抛出异常对象的时候,那么我们就必须处理这个异常对象 可以使用throws关键字处理异常对象, 会把异常对象声明抛出给方法的调用 ...
- 第二种方式读取并显示HDFS中的内容
1.讀取HDFS内容的java客戶端代碼: package Hdfs; import java.io.InputStream; import java.net.URI; import org.apac ...
- Struts2框架的数据封装一之属性封装(属性封装的第二种方式:封装成javaBean)
Struts2中提供了两类数据封装的方式? 第一种方式:属性驱动(有两种方式:一个对属性,另外一个是将参数封装到javaBean中) B. 在页面上,使用OGNL表达式进行数据封装.(将参数封装到ja ...
- SpringMVC实现操作的第二种方式
一: 运行效果: 点击提交之后显示效果 二: (1).web.xml <?xml version="1.0" encoding="UTF-8"?> ...
随机推荐
- 常见的transformation算子
RDD:RDD分区数,若从HDFS创建RDD,RDD的分区就是和文件块一一对应,若是集合并行化形式创建,RDD分区数可以指定,一般默认值是CPU的核数. task:task数量就是和分区数量对应. 一 ...
- MySQL Error:Warning: (1366, "Incorrect string value: '\\xF0\\x9F\\x98\\x82\\xF0\\x9F...' for column 'xxx' at row 2")
bug现象 使用连接数据库的可视化软件插入 emoj 表情数据.生僻字,可以正常插入.(导致我一直以为跟表情没有任何关系,谷歌出来一堆跟修改数据库.表.字段 的编码的结果....)但是一启动程序插入新 ...
- (2)ESP8266 矩阵的逆求解
#include "math.h" int N=4; int M=4; float a[4][4]={ {1,0,0,0}, {1,0.5,0,0}, {1,0,1,0}, {1, ...
- js 符号转换 html代码
S转换HTML转义符 //去掉html标签 function removeHtmlTab(tab) { return tab.replace(/<[^<>]+?>/g,''); ...
- Java Web 项目的文件/文件夹上传下载
需求: 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验: 内网百兆网络上传速度为12MB/S 服务器内存占用低 支持文件夹上传,文件夹中的文件数量达到1万个以上,且包 ...
- 控制论模型&心流模型&波模型
1.控制论模型 这是对设定的目标,通过多次输入和输出,反馈调节,最终达成目标的方法.广泛运用于自然科学与社会科学中.反馈的周期长短决定了调节精度的大小以及达到目标的速度.反馈结果与目标背离的立即纠正, ...
- GoCN每日新闻(2019-10-14)
GoCN每日新闻(2019-10-14) 1. 基于 Go 开源项目 MIMIO 的对象存储方案在探探的实践 https://mp.weixin.qq.com/s/YIKB_qAqqy6ydtFT_a ...
- 用DLL方式封装MDI子窗体
用DLL方式封装MDI子窗体是一种常用的软件研发技术,他的长处: 研发人员能够负责某一个模块的编写包括(界面+逻辑),能够互不干扰,模块研发完成后,主程式统一调用. 易于程式升级,当程式升级时,不用编 ...
- ZooKeeper和ZAB协议
前言 ZooKeeper是一个提供高可用,一致性,高性能的保证读写顺序的存储系统.ZAB协议为ZooKeeper专门设计的一种支持数据一致性的原子广播协议. 演示环境 $ uname -a Darwi ...
- On-line fusion of trackers for single-object tracking
On-line fusion of trackers for single-object tracking Pattern Recognition, 2018 - Elsevier 2019-08-1 ...