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. 洛谷九月月赛II

    题解:模拟 一旦不匹配就要break #include<iostream> #include<cstdio> #include<cstring> #include& ...

  2. python下的select模块使用 以及epoll与select、poll的区别

    python下的select模块使用 以及epoll与select.poll的区别 先说epoll与select.poll的区别(总结) 整理http://www.zhihu.com/question ...

  3. MySQL 练习题4

    1.表结构如下: #课程表 CREATE TABLE `course` ( `c_id` ) NOT NULL, `c_name` ) DEFAULT NULL, `t_id` ) DEFAULT N ...

  4. 基于typescript 强大的 nestjs 框架试用

    nestjs 一个nodejs 的graphql 框架 安装 npm i -g @nestjs/cli 初始化项目 nest new dalong 运行demo 使用yarn yarn start 添 ...

  5. pthread中取消线程

    取消线程:告诉一个线程关掉自己,取消操作允许线程请求终止其所在进程中的任何其他线程.不希望或不需要对一组相关的线程执行进一步操作时,可以选择执行取消操作.取消线程的一个示例是异步生成取消条件. 对于c ...

  6. php switch case的"bug"

    首先说明,这不是一个bug.应该说是一个比较容易中招的陷阱. 今天使用switch遇到一个问题,代码如下: <?php $num = 0; switch ($price) { case $pri ...

  7. highlight.js 设置行号

    原文地址:highlight.js 设置行号 博客地址:http://www.extlight.com 一.背景 笔者在开发这套博客系统时使用 Editormd 作为 Markdown 编辑器,由于不 ...

  8. c# 爬虫(三) 文件上传

    在上一篇中,我们说了模拟登录, 下面我们说说附件上传. 据说,最早的http协议是不支持附件上传的,后来有添加了一个RFC 2045 协议,才支持附件上传,关于附件上传,请参见 http://www. ...

  9. 移动端开发之px,em和rem详解

    px:表示的是绝对的像素值,1px就是1像素大小 em:关于em,网上有资料说是关于父元素的,但是其实个人感觉这种说法是不对的,其实em的大小是根据自身的font-size确定的,而只是正常的情况下子 ...

  10. 在Eclipse里静态导入

    静态导入import static 介绍见import static和import的区别 在Eclipse里配置静态导入,步骤见下面截图的箭头 例如导入下面的jar 常用的静态导入方法如下: com. ...