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系列(十)生产者消费者模式的更多相关文章

  1. java 多线程并发系列之 生产者消费者模式的两种实现

    在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据 ...

  2. java 多线程 22 :生产者/消费者模式 进阶 利用await()/signal()实现

    java多线程15 :wait()和notify() 的生产者/消费者模式 在这一章已经实现了  wait/notify 生产消费模型 利用await()/signal()实现生产者和消费者模型 一样 ...

  3. 2.5多线程(Java学习笔记)生产者消费者模式

    一.什么是生产者消费者模式 生产者生产数据存放在缓冲区,消费者从缓冲区拿出数据处理. 可能大家会问这样有何好处? 1.解耦 由于有了缓冲区,生产者和消费者之间不直接依赖,耦合度降低,便于程序拓展和维护 ...

  4. JAVA多线程编程之生产者消费者模式

    Java中有一个BlockingQueue可以用来充当堵塞队列,下面是一个桌面搜索的设计 package net.jcip.examples; import java.io.File; import ...

  5. day 28 :进程相关,进程池,锁,队列,生产者消费者模式

    ---恢复内容开始--- 前情提要: 一:进程Process  1:模块介绍 from multiprocessing import Process from multiprocessing impo ...

  6. Java Thread系列(十)Future 模式

    Java Thread系列(十)Future 模式 Future 模式适合在处理很耗时的业务逻辑时进行使用,可以有效的减少系统的响应时间,提高系统的吞吐量. 一.Future 模式核心思想 如下的请求 ...

  7. java多线程系列15 设计模式 生产者 - 消费者模式

    生产者-消费者 生产者消费者模式是一个非常经典的多线程模式,比如我们用到的Mq就是其中一种具体实现 在该模式中 通常会有2类线程,消费者线程和生产者线程 生产者提交用户请求 消费者负责处理生产者提交的 ...

  8. Java 生产者消费者模式详细分析

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  9. 基于Java 生产者消费者模式(详细分析)

    Java 生产者消费者模式详细分析 本文目录:1.等待.唤醒机制的原理2.Lock和Condition3.单生产者单消费者模式4.使用Lock和Condition实现单生产单消费模式5.多生产多消费模 ...

随机推荐

  1. 【转】Linux 图形界面与命令行模式切换

    原文网址:http://blog.csdn.net/ldl22847/article/details/7600368 Tip:使用环境VMware Workstation    OS:CentOS 6 ...

  2. unity的prefab(预设)例子

    prefab用于预先设置一些控件,在需要的时候直接引用,简化开发,当然,你完全可以用写代码解决 在场景内新建一个空物体,绑定一个脚本 void Start () { GameObject cube = ...

  3. selenium phantomjs java无界面浏览器环境搭建

    java selenium搭建无界面浏览器 1.http://phantomjs.org/ 下载windows版phantomjs 2.解压后bin目录下会有exe文件 3.测试代码: package ...

  4. Log4j(2)--日志等级

    Log4j根据日志信息的重要程度,分OFF.FATAL.ERROR.WARN.INFO.DEBUG.ALL 当然再细分的话 还有 FATAL(严重错误), 但是Log4j官方建议实际实用的话,Log4 ...

  5. Microsoft SQL Server on Linux破解 2G内存限制

    首先,贴上微软官方安装方法,大家按照官方的操作就行. 微软官方安装方法 相信很多同学遇到一个问题就是: sqlservr: This program requires a machine with a ...

  6. usaco 2009 12 过路费

    最近学的图论,oj上的这道题卡了我一上午,写一下总结. 题目描述: 跟所有人一样,农夫约翰以着宁教我负天下牛,休教天下牛负我(原文:宁我负人,休教人负我)的伟大精神,日日夜夜苦思生财之道.为了发财,他 ...

  7. C++指针的长度

    每台计算机都有字长,指明指针数据的标称大小----来自深入理解计算机系统 每台计算机的字长指明了它的虚拟空间大小.比如32位的机器,虚拟空间地址为0~2^w-1程序最多访问2^w个字节 对于32位程序 ...

  8. ES6系列_13之Proxy进行预处理(简单学习)

    1.理解什么是预处理? 当我们在操作一个对象或者方法时会有几种动作,比如:在运行函数前初始化一些数据,在改变对象值后做一些善后处理.这些都算钩子函数,Proxy的存在就可以让我们给函数加上这样的钩子函 ...

  9. OpenCL 图像卷积 1

    ▶ 书上的代码改进而成,从文件读入一张 256 阶灰度图,按照给定的卷积窗口计算卷积,并输出到文件中. ● 代码,使用 9 格的均值窗口,居然硬读写 .bmp 文件,算是了解一下该文件的具体格式,留作 ...

  10. Sonar及其eclipse插件的安装 详细 http://www.importnew.com/10017.html

    参考:http://www.importnew.com/10017.html