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线程中生产者与消费者的问题
一.概念 生产者与消费者问题是一个金典的多线程协作的问题.生产者负责生产产品,并将产品存放到仓库:消费者从仓库中获取产品并消费.当仓库满时,生产者必须停止生产,直到仓库有位置存放产品:当仓库空时,消费 ...
随机推荐
- PHP获取时间排除周六、周日的两个方法
//方法一: <?php $now = time(); //指定日期用法 $now = strtotime('2014-01-08') ; $day = 3600*24; $total = 12 ...
- 20180826(01)-Java数据结构
Java 数据结构 Java工具包提供了强大的数据结构.在Java中的数据结构主要包括以下几种接口和类: 枚举 (Enumeration) 位集合(BitSet) 向量 (Vector) 栈 (Sta ...
- hbuilder+vue单页应用打包成APP后退按钮返回上一页的问题
APP打包工具:hbuilder 需要js包:mui.js ,引入方法https://www.cnblogs.com/v616/p/11290281.html 实现原理:在vue根组件App.vue监 ...
- python 数字系列-无穷大与NaN
无穷大与NaN 问题 你想创建或测试正无穷.负无穷或NaN(非数字)的浮点数. 解决方案 Python并没有特殊的语法来表示这些特殊的浮点值,但是可以使用 float() 来创建它们.比如: > ...
- Integer自动装箱和拆箱
Integer a=3; => Integer a=Integer.valueOf(3); /** *@description: 自动装箱和拆箱 *@auther: yangsj *@ ...
- Oracle 一条sql插入多条数据
Oracle一次插入多条数据. 表结构: create table aa ( ID NUMBER(11) PRIMARY KEY, NAME VARCHAR2(20) ) 第一种方式: insert ...
- 将多个jpg文件以追加形式合并成一个文件_delphi教程 bmp 合并 http://www.west.cn/www/info/58058-1.htm
将多个jpg文件以追加形式合并成一个文件_delphi教程 作者:网友供稿 点击:0 西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!云服务器 ...
- python支持的进程与线程
一.multiprocessing模块介绍 python中的多线程无法利用CPU资源,在python中大部分情况使用多进程.python中提供了非常好的多进程包multiprocessing. mul ...
- MySQL-第一篇认识MySQL
1.什么是mysql mysql是一种关系型数据库,是瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品. 2.mysql的安装 下载mysql-installer-community- ...
- luoguP1505 [国家集训队]旅游(真的毒瘤)
luogu P1505 [国家集训队]旅游 题目 #include<iostream> #include<cstdio> #include<cstdlib> #in ...