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线程中生产者与消费者的问题
一.概念 生产者与消费者问题是一个金典的多线程协作的问题.生产者负责生产产品,并将产品存放到仓库:消费者从仓库中获取产品并消费.当仓库满时,生产者必须停止生产,直到仓库有位置存放产品:当仓库空时,消费 ...
随机推荐
- Python_005(字典无极坑)
一.字典(dict) 1.字典的定义格式:dic{key1:value1,key2,value2} :这里面key是唯一的,保存的时候,根据key计算一个内存地址,然后将key-value保存在这个地 ...
- 20180907-Java Applet基础
Java Applet基础 applet是一种Java程序.它一般运行在支持Java的Web浏览器内.因为它有完整的Java API支持,所以applet是一个全功能的Java应用程序. 如下所示是独 ...
- Nexus Repository OSS 3安装配置使用
Nexus Repository OSS 3是一个开源的仓库管理系统,提供了更加丰富的功能,而且安装.配置.使用起来也更加简单方便.OSS 3版本主要支持的仓库(Repository)包括如下: bo ...
- 浅析java中的string
在学习java36讲的时候看到评论区有人提出的一个问题: String s1 = new String("do"); s1.intern(); String s2 = " ...
- 【数据库】一篇文章搞掂:Oracle数据库
PL/SQL的使用 1.安装使用 1.1.安装暂略 1.2.使用 添加环境变量 打开PL/SQL,不要登录,进入界面后,打开设置Preference 设置主目录和OCI库
- python web自动化测试框架搭建(功能&接口)——接口测试模块
Python接口测试采用python读取excel的方法,通过requests库发送请求和接收响应.模块有: Data:用于存放excel用例的,用例格式: iutil: 接口公共方法,数据引擎.ht ...
- 进程之间的通讯Queue简单应用
#进程间通讯--Queue #Process有时需要通信的,操作系统提供了很多机制来实现进程之间的通讯 #而Queue就是其中一个 #1.Queue的使用 #可以使用multiprocessing模块 ...
- jmeter设置全局变量token
返回登录后的token使用json path Extractor插件,定位到获取后的token为变量 在登录下后置处理器下添加json path Extracto插件 根据上面获取到的token位置路 ...
- python装饰器(基础中的重点)
一.简单的装饰器 1.为什么要使用装饰器呢? 装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展 装饰器的本质:就是一个闭包函数 那么我们先来看一个简单的装饰器:实现计算每个函数的执 ...
- MySql-第七篇单表查询
1.MySQL中可以使用+.-.*./. 1>但MySQL中没有提供字符串连接运算符,可以使用concat(a_str,'xxx')进行连接. 2>在算术表达式中使用null,将会导致整个 ...