Java Thread系列(十)生产者消费者模式
Java Thread系列(十)生产者消费者模式
生产者消费者问题(producer-consumer problem),是一个多线程同步问题的经典案例。该问题描述了两个共亨固定大小缓冲区的线程—即所谓的“生产者”和“消费者—在实际运行时会发生的问题。
一、信号灯法
信号灯法实际上就是保证同一时间只有一个线程在操作数据,操作完成后通知其它线程,从而避免死锁。
(1) 生产者
public class Producer implements Runnable {
private Data data;
public Producer(Data data) {
this.data = data;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
data.produce(String.format("product-%s", i));
}
}
}
(2) 消费者
public class Consumer implements Runnable {
private Data data;
public Consumer(Data data) {
this.data = data;
}
@Override
public void run() {
while (true) {
data.consume();
}
}
}
(3) 数据
public class Data {
private String data;
// flag = true 生产者生产,消费者等待,生产完毕后通知消费者消费
// flag = false 消费者消费,生产者等待,消费完毕后通知生产者生产
private boolean flag = true;
public synchronized void consume() {
if (flag) {
try {
wait();
} catch (InterruptedException e) {
;
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
;
}
notify();
System.out.println("消费者消费:" + getData());
flag = true;
}
public synchronized void produce(String data) {
if (!flag) {
try {
wait();
} catch (InterruptedException e) {
;
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
;
}
notify();
System.out.println("生产者生产:" + data);
setData(data);
flag = false;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
(4) 测试
public static void main(String[] args) {
Data data = new Data();
new Thread(new Producer(data)).start();
new Thread(new Consumer(data)).start();
}
二、容器法
(1) Producter
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class Producter implements Runnable {
private BlockingQueue<Data> data;
//用于生成id
private static AtomicInteger count = new AtomicInteger(0);
public Producter(BlockingQueue<Data> data) {
this.data = data;
}
public Producter() { }
@Override
//生产者生产数据
public void run() {
try {
Thread.sleep(2000);
int id = count.incrementAndGet();
if (!this.data.offer(new Data(id, "data-" + id), 2, TimeUnit.SECONDS)) {
System.out.printf("%s生产:data-%s失败\n", Thread.currentThread().getName(), id);
} else {
System.out.printf("%s生产:data-%s\n", Thread.currentThread().getName(), id);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
(2) Consumer
import java.util.concurrent.BlockingQueue;
public class Consumer implements Runnable {
private BlockingQueue<Data> data;
public Consumer(BlockingQueue<Data> data) {
this.data = data;
}
public Consumer() { }
@Override
//消费者消费数据
public void run() {
Data d = null;
try {
d = this.data.take();
System.out.printf("%s消费:%s\n", Thread.currentThread().getName(), d.getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Data {
private int id;
private String name;
}
(3) 测试
LinkedBlockingQueue<Data> data = new LinkedBlockingQueue<Data>();
Producter p1 = new Producter(data);
Producter p2 = new Producter(data);
Producter p3 = new Producter(data);
Consumer c1 = new Consumer(data);
Consumer c2 = new Consumer(data);
Consumer c3 = new Consumer(data);
ExecutorService pool = Executors.newCachedThreadPool();
pool.execute(p1);
pool.execute(p2);
pool.execute(p3);
pool.execute(c1);
pool.execute(c2);
pool.execute(c3);
pool.shutdown();
每天用心记录一点点。内容也许不重要,但习惯很重要!
Java Thread系列(十)生产者消费者模式的更多相关文章
- java 多线程并发系列之 生产者消费者模式的两种实现
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据 ...
- java 多线程 22 :生产者/消费者模式 进阶 利用await()/signal()实现
java多线程15 :wait()和notify() 的生产者/消费者模式 在这一章已经实现了 wait/notify 生产消费模型 利用await()/signal()实现生产者和消费者模型 一样 ...
- 2.5多线程(Java学习笔记)生产者消费者模式
一.什么是生产者消费者模式 生产者生产数据存放在缓冲区,消费者从缓冲区拿出数据处理. 可能大家会问这样有何好处? 1.解耦 由于有了缓冲区,生产者和消费者之间不直接依赖,耦合度降低,便于程序拓展和维护 ...
- JAVA多线程编程之生产者消费者模式
Java中有一个BlockingQueue可以用来充当堵塞队列,下面是一个桌面搜索的设计 package net.jcip.examples; import java.io.File; import ...
- day 28 :进程相关,进程池,锁,队列,生产者消费者模式
---恢复内容开始--- 前情提要: 一:进程Process 1:模块介绍 from multiprocessing import Process from multiprocessing impo ...
- Java Thread系列(十)Future 模式
Java Thread系列(十)Future 模式 Future 模式适合在处理很耗时的业务逻辑时进行使用,可以有效的减少系统的响应时间,提高系统的吞吐量. 一.Future 模式核心思想 如下的请求 ...
- java多线程系列15 设计模式 生产者 - 消费者模式
生产者-消费者 生产者消费者模式是一个非常经典的多线程模式,比如我们用到的Mq就是其中一种具体实现 在该模式中 通常会有2类线程,消费者线程和生产者线程 生产者提交用户请求 消费者负责处理生产者提交的 ...
- Java 生产者消费者模式详细分析
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- 基于Java 生产者消费者模式(详细分析)
Java 生产者消费者模式详细分析 本文目录:1.等待.唤醒机制的原理2.Lock和Condition3.单生产者单消费者模式4.使用Lock和Condition实现单生产单消费模式5.多生产多消费模 ...
随机推荐
- python print 控制台输出中文
在pycharm里面的控制台用print输出信息, 本意想输出中文, 但是实际上是u\xxxx. 可以用这种方式: print("%s " % cn_string)
- sourcegraph 方便的代码查看工具
sourcegraph 是一个方便的代码查看插件,有chrome 的插件,具体安装可以在chrome 应用商店,同时 官方提供了基于docker 运行的方式(适合本地使用) 下载镜像 docker p ...
- C# 判断操作系统的位数
判断操作系统的位数有一下几种方法: 1. 特征值IntPtr 2. WMI 1的实现如下: public static int GetOSInfo() { if (IntPtr.Size == 8) ...
- 文件和I/O流
版权声明:本文为[博主](https://zhangkn.github.io)原创文章,未经博主同意不得转载.https://creativecommons.org/licenses/by-nc-sa ...
- Scriptcase v8推出内部測试版及价格调整
PHP代码生成器Scriptcase如今已经内部推出了v8.0版本号,8.0相比于曾经的版本号做了大幅度调整.我们将在完好測试的基础上发表8.0的相关文章. 另,即日起,Scriptcase的20%优 ...
- POJ3259 Wormholes 【Bellmanford推断是否存在负回路】
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u011775691/article/details/27612757 非常easy的bellmanf ...
- solr5.5.0在CenOS上的安装与配置
solr5.5.0在CenOS上的安装与配置 1. Solr简介 Solr是一个基于Lucene的Java搜索引擎服务器.Solr 提供了层面搜索.命中醒目显示并且支持多种输出格式(包括 XML/XS ...
- bzoj2330糖果
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2330 差分约束裸题.练习用spfa判正环(一个点入队超过n次). 据说有1e5个点连成一条链 ...
- 手动更新花生壳域名的动态IP
http://帐号:密码@ddns.oray.com/ph/update?hostname=hahaha.vicp.cc&myip=182.xx.200.xx 花生壳的文档地址 例子 1.使用 ...
- laravel 控制器中使用 try catch
需要操作数据库时,当数据字段不一致,mysql报错,控制程序,需要使用try catch 下面是使用案例 $morder['morder_time'] = time();//在这里使用try catc ...