21.使用LinkedBlockingQueue模拟生产者与消费者
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 生产者
*/
public class ProducerThread implements Runnable {
private BlockingQueue queue;
private volatile boolean flag = true;
private static AtomicInteger count = new AtomicInteger();
public ProducerThread(BlockingQueue queue) {
this.queue = queue;
}
@Override
public void run() {
try {
System.out.println("生产线程启动...");
while (flag){
System.out.println("正在生产...");
String data = count.incrementAndGet() + "";
boolean offer = queue.offer(data, 2, TimeUnit.SECONDS);
if (offer){
System.out.println("生产者存入"+data+"到队列成功");
}else {
System.out.println("生产者存入"+data+"到队列失败");
}
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
System.out.println("生产结束");
}
}
public void stop(){
this.flag = false;
}
}
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* 消费者
*/
public class ConsumerThread implements Runnable{
private BlockingQueue<String> queue;
private volatile boolean flag = true;
public ConsumerThread(BlockingQueue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
try {
System.out.println("消费线程启动...");
while (flag){
System.out.println("消费者正在获取数据...");
String data = queue.poll(2, TimeUnit.SECONDS);
if (data!=null){
System.out.println("消费者拿到队列中的数据:"+data);
Thread.sleep(1000);
}else {
System.out.println("消费者未拿到队列中的数据");
flag = false;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
System.out.println("消费者结束");
}
}
}
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* LinkedBlockingQueue阻塞队列大小的配置是可选的,如果我们初始化时指定一个大小,它就是有边界的,
* 如果不指定,它就是无边界的。说是无边界,其实是采用了默认大小为Integer.MAX_VALUE的容量 。它的内部实现是一个链表。
* 和ArrayBlockingQueue一样,LinkedBlockingQueue 也是以先进先出的方式存储数据,最新插入的对象是尾部,最新移出的对象是头部
*/
public class Main {
public static void main(String[] args) throws InterruptedException{
BlockingQueue<String> queue = new LinkedBlockingQueue<>(10);
ProducerThread producerThread1 = new ProducerThread(queue);
ProducerThread producerThread2 = new ProducerThread(queue);
ConsumerThread consumerThread = new ConsumerThread(queue);
Thread t1 = new Thread(producerThread1);
Thread t2 = new Thread(producerThread2);
Thread t3 = new Thread(consumerThread);
t1.start();
t2.start();
t3.start();
Thread.sleep(10000);
producerThread1.stop();
producerThread2.stop();
}
//生产线程启动...
//正在生产...
//消费线程启动...
//消费者正在获取数据...
//生产线程启动...
//正在生产...
//生产者存入1到队列成功
//生产者存入2到队列成功
//消费者拿到队列中的数据:2
//正在生产...
//生产者存入3到队列成功
//正在生产...
//生产者存入4到队列成功
//消费者正在获取数据...
//消费者拿到队列中的数据:1
//正在生产...
//消费者正在获取数据...
//正在生产...
//消费者拿到队列中的数据:3
//生产者存入5到队列成功
//生产者存入6到队列成功
//消费者正在获取数据...
//正在生产...
//正在生产...
//生产者存入8到队列成功
//生产者存入7到队列成功
//消费者拿到队列中的数据:4
//正在生产...
//消费者正在获取数据...
//正在生产...
//消费者拿到队列中的数据:5
//生产者存入9到队列成功
//生产者存入10到队列成功
//消费者正在获取数据...
//消费者拿到队列中的数据:6
//正在生产...
//正在生产...
//生产者存入11到队列成功
//生产者存入12到队列成功
//消费者正在获取数据...
//正在生产...
//正在生产...
//生产者存入13到队列成功
//消费者拿到队列中的数据:7
//生产者存入14到队列成功
//正在生产...
//生产者存入15到队列成功
//正在生产...
//消费者正在获取数据...
//生产者存入16到队列成功
//消费者拿到队列中的数据:8
//正在生产...
//消费者正在获取数据...
//正在生产...
//消费者拿到队列中的数据:9
//生产者存入17到队列成功
//生产者存入18到队列成功
//消费者正在获取数据...
//正在生产...
//生产者存入19到队列成功
//正在生产...
//消费者拿到队列中的数据:10
//生产者存入20到队列成功
//消费者正在获取数据...
//生产结束
//生产结束
//消费者拿到队列中的数据:11
//消费者正在获取数据...
//消费者拿到队列中的数据:12
//消费者正在获取数据...
//消费者拿到队列中的数据:13
//消费者正在获取数据...
//消费者拿到队列中的数据:14
//消费者正在获取数据...
//消费者拿到队列中的数据:15
//消费者正在获取数据...
//消费者拿到队列中的数据:16
//消费者正在获取数据...
//消费者拿到队列中的数据:17
//消费者正在获取数据...
//消费者拿到队列中的数据:18
//消费者正在获取数据...
//消费者拿到队列中的数据:19
//消费者正在获取数据...
//消费者拿到队列中的数据:20
//消费者正在获取数据...
//消费者未拿到队列中的数据
//消费者结束
}
案例二:
/**
* 任务 生产者向缓冲区提交的数据
*/
public final class PCData {
private final int intData;
public PCData(int d) {
this.intData = d;
}
public int getData(){
return intData;
}
@Override
public String toString() {
return "data:"+intData;
}
}
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 生产者 用于提交用户请求,提取用户任务,并装入内存缓冲区
*/
public class Producer implements Runnable{
private volatile boolean isRunning = true;
// 共享内存缓存区 缓存生产者提交的任务或数据,供消费者使用
private BlockingQueue<PCData> queue;
// 总数
private static AtomicInteger count = new AtomicInteger();
private static final int SLEEPTIME = 1000;
public Producer(BlockingQueue<PCData> queue) {
this.queue = queue;
}
@Override
public void run() {
PCData data = null;
Random r = new Random();
System.out.println("start Producer id="+Thread.currentThread().getId());
try {
while (isRunning){
Thread.sleep(r.nextInt(SLEEPTIME));
//构造任务数据
data = new PCData(count.incrementAndGet());
System.out.println(data+" is put into queue");
//提交数据到缓冲区
if (!queue.offer(data,2, TimeUnit.SECONDS)){
System.out.println("failed to put data: " + data);
}
}
} catch (Exception e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
public void stop(){
isRunning = false;
}
}
import java.text.MessageFormat;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
/**
* 消费者 在内存缓冲区中提取处理任务
* poll -->【若队列为空,返回null】
* remove >【若队列为空,抛出NoSuchElementException异常】
* take -->【若队列为空,发生阻塞,等待有元素】
*/
public class Consumer implements Runnable{
private BlockingQueue<PCData> queue;
private static final int SLEEPTIME = 1000;
public Consumer(BlockingQueue<PCData> queue) {
this.queue = queue;
}
@Override
public void run() {
Random r = new Random();
System.out.println("start Consumer id="+Thread.currentThread().getId());
try {
while (true){
PCData data = queue.take();//提取任务
int re = data.getData()*data.getData(); //计算平方
System.out.println(MessageFormat.format("{0}*{1}={2}"
,data.getData(),data.getData(),re));
Thread.sleep(r.nextInt(SLEEPTIME));
}
} catch (Exception e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
/**
* 使用生产者和消费者的客户端
*/
public class Main {
public static void main(String[] args) throws InterruptedException {
//建立缓冲区
BlockingQueue<PCData> q = new LinkedBlockingQueue<>();
//建立生产者
Producer p1 = new Producer(q);
Producer p2 = new Producer(q);
Producer p3 = new Producer(q);
//建立消费者
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
Consumer c3 = new Consumer(q);
//建立线程池
ExecutorService service = Executors.newCachedThreadPool();
service.execute(p1);
service.execute(p2);
service.execute(p3);
service.execute(c1);
service.execute(c2);
service.execute(c3);
Thread.sleep(10000);
//停止生产者
p1.stop();
p2.stop();
p3.stop();
Thread.sleep(3000);
service.shutdown();
}
}
21.使用LinkedBlockingQueue模拟生产者与消费者的更多相关文章
- java线程(2)——模拟生产者与消费者
前言: 我们都听说过生产者和消费者的例子吧,现在来模拟一下.生产者生产面包,消费者消费面包.假定生产者将生成出来的面包放入篮子中,消费者从篮子中取.这样,当篮子中没有面包时,消费者不能取.当篮子满了以 ...
- 【java线程系列】java线程系列之线程间的交互wait()/notify()/notifyAll()及生产者与消费者模型
关于线程,博主写过java线程详解基本上把java线程的基础知识都讲解到位了,但是那还远远不够,多线程的存在就是为了让多个线程去协作来完成某一具体任务,比如生产者与消费者模型,因此了解线程间的协作是非 ...
- java简单模拟生产者消费者问题
本文来自:http://www.cnblogs.com/happyPawpaw/archive/2013/01/18/2865957.html 引言 生产者和消费者问题是线程模型中的经典问题:生产者和 ...
- java多线程模拟生产者消费者问题,公司面试常常问的题。。。
package com.cn.test3; //java多线程模拟生产者消费者问题 //ProducerConsumer是主类,Producer生产者,Consumer消费者,Product产品 // ...
- LinkedBlockingQueue 实现 生产者 消费者
转载:https://blog.csdn.net/sinat_36553913/article/details/79533606 Java中使用LinkedBlockingQueue实现生产者,消费者 ...
- Java实现生产者和消费者
生产者和消费者问题是操作系统的经典问题,在实际工作中也常会用到,主要的难点在于协调生产者和消费者,因为生产者的个数和消费者的个数不确定,而生产者的生成速度与消费者的消费速度也不一样,同时还要实现生产者 ...
- Java中生产者与消费者模式
生产者消费者模式 首先来了解什么是生产者消费者模式.该模式也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例.该问题描述了两个共享固定大小缓冲区的线 ...
- java_Thread生产者与消费者 Demo
package com.bjsxt.Thread.Demo; public class ProducerConsumer { /** * 生产者与消费者 * @param args */ public ...
- java线程中生产者与消费者的问题
一.概念 生产者与消费者问题是一个金典的多线程协作的问题.生产者负责生产产品,并将产品存放到仓库:消费者从仓库中获取产品并消费.当仓库满时,生产者必须停止生产,直到仓库有位置存放产品:当仓库空时,消费 ...
随机推荐
- BZOJ 3306: 树 LCT + set 维护子树信息
可以作为 LCT 维护子树信息的模板,写的还是比较优美的. 本地可过,bzoj 时限太紧,一直 TLE #include<bits/stdc++.h> #define setIO(s) f ...
- select自定义箭头问题 。。。和一行内不同颜色的整体鼠标滑过变色
1.select自定义箭头问题 用<select><option></option></select>的时候自带的三角箭头与需要的三角不同,这是还要求有 ...
- Xcode编辑器之filter查找功能和查看最近修改的文件
一,前言 有时候,我们的项目过大,创建类过多就会造成“目标文件”不好查找.这时候通过“filter”进行目录结构筛选无疑是最好的选择. 二,什么是filiter filiter 顾名思义为“过滤”,“ ...
- Webstorm软件快捷键
默认配置-Eclipse的常用快捷键对照表 查找/代替 Webstorm快捷键 Eclipse快捷键 说明 ctrl+shift+N ctrl+shift+R 通过文件名快速查找工程内的文件(必记) ...
- xpath的几个常用规则
我们在定位页面元素的时候呢,经常使用到xpath.xpah定位元素,我们可以使用开发者工具,然后右键选取元素的xpath ,但是这种方式得到的xpath是绝对路径,如果页面元素发生变动,经常会出现定位 ...
- CAD到ArcGIS相关操作
1.Ctrl+N(新建图形)→复制原数据,粘贴到原坐标 2.将CAD数据转为矢量数据方法众多,此处将提供三种方法: 方法一:CAD转地理数据库注记 在[ArcToolBox]窗口中,双击[转换工具]→ ...
- 拒绝从入门到放弃_《Openstack 设计与实现》必读目录
目录 目录 关于这本书 必看知识点 最后 关于这本书 <Openstack 设计与实现>是一本非常值得推荐的书,为数不多的 Openstack 开发向中文书籍中的精品.如果希望从事 Ope ...
- 【ABAP系列】SAP ABAP-模块 字符串操作基础知识
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP-模块 字符串操 ...
- git团队协作代码提交步骤
我们公司由五个人同时开发一个项目,大佬建好仓库后叫我们统一提交到dev这个分支,我的分支是hardy,你们只要将这两个值改成你们团队协作中使用的分支即可.代码如下: git add . git com ...
- Swipe-移动端触摸滑动插件swipe.js
原文链接:http://caibaojian.com/swipe.html 插件特色 viaswipe.JS是一个比较有名的触摸滑动插件,它能够处理内容滑动,支持自定义选项,你可以让它自动滚动,控制滚 ...