生产者和消费者模型都是所有多线程开发应用中一个最为经典的方法,下面我给大家整理了一个生产者和消费者模型的例子,供各位参考参考。

下面的代码讲述了一个故事

一个面包生产铺里目前有30个面包,有三个人来买面包,第一个人要买50个,第二个要买20个,第三个要买30个。

第一个人不够,所以等着,让第二个买了。面包铺继续生产面包。有7个人在生产。

 代码如下 复制代码

package com.javaer.thread;

public class CPMode {

public static void main(String[] args) {

Godown godown = new Godown(30); //初始化库存 30个食物

Consumer c1 = new Consumer(50, godown);

Consumer c2 = new Consumer(20, godown);

Consumer c3 = new Consumer(30, godown);

Producer p1 = new Producer(10, godown);

Producer p2 = new Producer(10, godown);

Producer p3 = new Producer(10, godown);

Producer p4 = new Producer(10, godown);

Producer p5 = new Producer(10, godown);

Producer p6 = new Producer(10, godown);

Producer p7 = new Producer(80, godown);

c1.start();

c2.start();

c3.start();

p1.start();

p2.start();

p3.start();

p4.start();

p5.start();

p6.start();

p7.start();

}

}

/**

* 仓库

*/

class Godown {

public static final int max_size = 100; //最大库存量

public int curnum;     //当前库存量

Godown() {

}

Godown(int curnum) {

this.curnum = curnum;

}

/**

* 生产指定数量的产品

*

* @param neednum

*/

public synchronized void produce(int neednum) {

//测试是否需要生产

while (neednum curnum > max_size) {

System.out.println("要生产的产品数量" neednum "超过剩余库存量" (max_size - curnum) ",暂时不能执行生产任务!");

try {

//当前的生产线程等待

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

//满足生产条件,则进行生产,这里简单的更改当前库存量

curnum = neednum;

System.out.println("已经生产了" neednum "个产品,现仓储量为" curnum);

//唤醒在此对象监视器上等待的所有线程

notifyAll();

}

/**

* 消费指定数量的产品

*

* @param neednum

*/

public synchronized void consume(int neednum) {

//测试是否可消费

while (curnum < neednum) {

try {

//当前的消费线程等待

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

//满足消费条件,则进行消费,这里简单的更改当前库存量

curnum -= neednum;

System.out.println("已经消费了" neednum "个产品,现仓储量为" curnum);

//唤醒在此对象监视器上等待的所有线程

notifyAll();

}

}

/**

* 生产者

*/

class Producer extends Thread {

private int neednum;                //生产产品的数量

private Godown godown;            //仓库

Producer(int neednum, Godown godown) {

this.neednum = neednum;

this.godown = godown;

}

public void run() {

//生产指定数量的产品

godown.produce(neednum);

}

}

/**

* 消费者

*/

class Consumer extends Thread {

private int neednum;                //生产产品的数量

private Godown godown;            //仓库

Consumer(int neednum, Godown godown) {

this.neednum = neednum;

this.godown = godown;

}

public void run() {

//消费指定数量的产品

godown.consume(neednum);

}

}

已经消费了20个产品,现仓储量为10

已经生产了10个产品,现仓储量为20

已经生产了10个产品,现仓储量为30

已经生产了10个产品,现仓储量为40

已经生产了10个产品,现仓储量为50

已经消费了30个产品,现仓储量为20

已经生产了80个产品,现仓储量为100

已经消费了50个产品,现仓储量为50

已经生产了10个产品,现仓储量为60

已经生产了10个产品,现仓储量为70

注意:

实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了。

对于此模型,应该明确一下几点:

1、生产者仅仅在仓储未满时候生产,仓满则停止生产。

2、消费者仅仅在仓储有产品时候才能消费,仓空则等待。

3、当消费者发现仓储没产品可消费时候会通知生产者生产。

4、生产者在生产出可消费产品时候,应该通知等待的消费者去消费。

例子二

package cn.thread;

import java.util.concurrent.BlockingQueue;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.LinkedBlockingQueue;

/**

* java多线程模拟生产者消费者问题

*

* ProducerConsumer是主类,Producer生产者,Consumer消费者,Product产品,Storage仓库

*

* @author 林计钦

* @version 1.0 2013-7-24 下午04:49:02

*/

public class ProducerConsumer {

public static void main(String[] args) {

ProducerConsumer pc = new ProducerConsumer();

Storage s = pc.new Storage();

ExecutorService service = Executors.newCachedThreadPool();

Producer p = pc.new Producer("张三", s);

Producer p2 = pc.new Producer("李四", s);

Consumer c = pc.new Consumer("王五", s);

Consumer c2 = pc.new Consumer("老刘", s);

Consumer c3 = pc.new Consumer("老林", s);

service.submit(p);

//service.submit(p2);

service.submit(c);

service.submit(c2);

service.submit(c3);

}

/**

* 消费者

*

* @author 林计钦

* @version 1.0 2013-7-24 下午04:53:30

*/

class Consumer implements Runnable {

private String name;

private Storage s = null;

public Consumer(String name, Storage s) {

this.name = name;

this.s = s;

}

public void run() {

try {

while (true) {

System.out.println(name "准备消费产品.");

Product product = s.pop();

System.out.println(name "已消费(" product.toString() ").");

System.out.println("===============");

Thread.sleep(500);

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

/**

* 生产者

*

* @author 林计钦

* @version 1.0 2013-7-24 下午04:53:44

*/

class Producer implements Runnable {

private String name;

private Storage s = null;

public Producer(String name, Storage s) {

this.name = name;

this.s = s;

}

public void run() {

try {

while (true) {

Product product = new Product((int) (Math.random() * 10000)); // 产生0~9999随机整数

System.out.println(name "准备生产(" product.toString() ").");

s.push(product);

System.out.println(name "已生产(" product.toString() ").");

System.out.println("===============");

Thread.sleep(500);

}

} catch (InterruptedException e1) {

e1.printStackTrace();

}

}

}

/**

* 仓库,用来存放产品

*

* @author 林计钦

* @version 1.0 2013-7-24 下午04:54:16

*/

public class Storage {

BlockingQueue queues = new LinkedBlockingQueue(10);

/**

* 生产

*

* @param p

*            产品

* @throws InterruptedException

*/

public void push(Product p) throws InterruptedException {

queues.put(p);

}

/**

* 消费

*

* @return 产品

* @throws InterruptedException

*/

public Product pop() throws InterruptedException {

return queues.take();

}

}

/**

* 产品

*

* @author 林计钦

* @version 1.0 2013-7-24 下午04:54:04

*/

public class Product {

private int id;

public Product(int id) {

this.id = id;

}

public String toString() {// 重写toString方法

return "产品:" this.id;

}

}

}

结果

张三准备生产(产品:3359).

张三已生产(产品:3359).

===============

老刘准备消费产品.

王五已消费(产品:3359).

===============

王五准备消费产品.

张三准备生产(产品:1863).

张三已生产(产品:1863).

===============

老林已消费(产品:1863).

===============

老林准备消费产品.

张三准备生产(产品:5424).

张三已生产(产品:5424).

老刘已消费(产品:5424).

===============

===============

张三准备生产(产品:6290).

张三已生产(产品:6290).

===============

老刘准备消费产品.

王五已消费(产品:6290).

===============

张三准备生产(产品:990).

张三已生产(产品:990).

===============

老林已消费(产品:990).

===============

王五准备消费产品.

张三准备生产(产品:1971).

老林准备消费产品.

老刘已消费(产品:1971).

===============

张三已生产(产品:1971).

===============

张三准备生产(产品:5622).

老刘准备消费产品.

张三已生产(产品:5622).

===============

王五已消费(产品:5622).

===============

王五准备消费产品.

张三准备生产(产品:6570).

张三已生产(产品:6570).

===============

老林已消费(产品:6570).

===============

老林准备消费产品.

张三准备生产(产品:17).

老刘已消费(产品:17).

===============

张三已生产(产品:17).

===============

老刘准备消费产品.

张三准备生产(产品:7962).

张三已生产(产品:7962).

===============

王五已消费(产品:7962).

===============

王五准备消费产品.

张三准备生产(产品:3200).

张三已生产(产品:3200).

===============

老林已消费(产品:3200).

===============

老林准备消费产品.

张三准备生产(产品:7234).

张三已生产(产品:7234).

===============

老刘已消费(产品:7234).

===============

老刘准备消费产品.

张三准备生产(产品:6486).

张三已生产(产品:6486).

===============

王五已消费(产品:6486).

===============

张三准备生产(产品:5436).

王五准备消费产品.

王五已消费(产品:5436).

===============

java多线程生产消费者_java多线程 生产消费者模型相关推荐

  1. java多线程 生产者消费者_java多线程之-生产者与消费者

    java多线程之-并发协作[生产者与消费者]模型 对于多线程程序来说,不管c/c++ java python 等任何编程语言,生产者与消费者模型都是最为经典的.也就是可以说多线程的并发协作 对于此模型 ...

  2. java 锁旗标_Java多线程

    Java多线程 1. 多线程存在的意义 多线程最大的作用就是能够创建"灵活响应"的桌面程序,而编写多线程最大的困难就是不同线程之间共享资源的问题,要使这些资源不会同时被多个线程访问 ...

  3. java 读者写者_Java实现生产者消费者问题与读者写者问题详解

    1.生产者消费者问题 生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品.解决生产者/消费者问题的方法可分为两 ...

  4. java线程代码实现_Java 多线程代码实现讲解

    作为一个完全面向对象的语言,Java提供了类 java.lang.Thread 来方便多线程编程,这个类提供了大量的方法来方便我们控制自己的各个线程.那么如何提供给 Java 我们要线程执行的代码呢? ...

  5. java线程怎么用_Java多线程基本使用

    一.概念 1.进程 1.1进程:是一个正在进行中的程序,每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元. 1.2线程:就是进程中一个独立的控制单元,线程在控制着进程的执行,一 ...

  6. java 生产者消费者_Java多线程:线程间通信—生产者消费者模型

    一.背景 && 定义 多线程环境下,只要有并发问题,就要保证数据的安全性,一般指的是通过 synchronized 来进行同步. 另一个问题是, 多个线程之间如何协作呢 ? 我们看一个 ...

  7. java多线程 生产者消费者_java多线程之生产者消费者经典问题 - 很不错的范例

    /**生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二,既然是生产者.消费者,那么生产者类和消费者类就是必须的 * 第三,生产什么,消费什么,所以物品类是必须的,这里 ...

  8. java 多线程变量可见性_Java多线程:易变变量,事前关联和内存一致性

    java 多线程变量可见性 什么是volatile变量? volatile是Java中的关键字. 您不能将其用作变量或方法名称. 期. 我们什么时候应该使用它? 哈哈,对不起,没办法. 当我们在多线程 ...

  9. java 管程通信_Java多线程07_线程通信之管程法与信号灯法

    Java多线程07_线程通信之管程法与信号灯法 线程通信 的应用场景是 消费者/生产者问题: 解决线程通信的方法: wait()表示线程一直等待,直到接到通知(会释放锁) wait(long time ...

  10. java线程集合点_Java多线程学习笔记(三) 甚欢篇

    使人有乍交之欢,不若使其无久处之厌 <小窗幽记>很多时候,我们需要的都不是再多一个线程,我们需要的线程是许多个,我们需要让他们配合.同时我们还有一个愿望就是复用线程,就是将线程当做一个工人 ...

最新文章

  1. 爬虫时出现 IndexError: list index out of range 的原因
  2. 20w7珠led驱动电源电路图_三种常用的LED驱动电源电路图详解!
  3. 模版引擎总结之综合分析模版引擎
  4. iOS之由身份证号返回性别
  5. [css] 为什么要使用sass/less?
  6. LeetCode 1305. 两棵二叉搜索树中的所有元素(二叉树迭代器)
  7. asp 更新 mysql数据库_ASP如何使用MYSQL数据库
  8. 【学习总结】数学-基本计数方法
  9. 如何用python制作五子棋游戏_Python制作打地鼠小游戏
  10. TEncCu::xCheckRDCostMerge2Nx2N
  11. 【安全狐】CVE-2015-5254_ActiveMQ反序列化漏洞复现
  12. 信奥中的数学:卷积、傅立叶变换
  13. 全球AI泰斗Stuart Rusell:研究人工智能太诱人了,不可抗拒
  14. 用计算机完成韩信点兵,韩信点兵问题.PPT
  15. java蓝桥杯练习 蜜蜂飞舞
  16. 考虑储能削峰填谷的含DG配电网可靠性评估
  17. 百度为什么打不开!最新消息~
  18. DataStage问题汇总
  19. 京东超级秒杀时间html,京东418超级秒杀节LOGO及使用规范
  20. 面向智能机器人的通讯安全机制研究与改进

热门文章

  1. Zorin OS:Windows用户无痛转移Linux
  2. MapReduce :通过数据具有爷孙关系的结果
  3. 兼容ie\firefox\chrome的cursor
  4. 控件内部显示不正确原因---没有调用layoutSubview的父类方法
  5. ueditor-图片上传是报错
  6. iOS 动态添加属性方法
  7. 任何BUG都会被发现
  8. 4.Jenkins 2 权威指南 --- 通知与报告
  9. 19.TCP/IP 详解卷1 --- TCP 的交互数据流
  10. 循序渐进之Spring AOP(5) - 创建切面