对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的。就像学习每一门编程语言一样,Hello World!都是最经典的例子。

实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了。
对于此模型,应该明确一下几点:
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<Product> queues = new LinkedBlockingQueue<Product>(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多线程-并发协作(生产者消费者模型)的更多相关文章

  1. Java多线程14:生产者/消费者模型

    什么是生产者/消费者模型 一种重要的模型,基于等待/通知机制.生产者/消费者模型描述的是有一块缓冲区作为仓库,生产者可将产品放入仓库,消费者可以从仓库中取出产品,生产者/消费者模型关注的是以下几个点: ...

  2. java线程基础巩固---多线程下的生产者消费者模型,以及详细介绍notifyAll方法

    在上一次[http://www.cnblogs.com/webor2006/p/8419565.html]中演示了多Product多Consumer假死的情况,这次解决假死的情况来实现一个真正的多线程 ...

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

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

  4. Java多线程之并发协作生产者消费者设计模式

    两个线程一个生产者个一个消费者 需求情景 两个线程,一个负责生产,一个负责消费,生产者生产一个,消费者消费一个 涉及问题 同步问题:如何保证同一资源被多个线程并发访问时的完整性.常用的同步方法是采用标 ...

  5. JAVA多线程经典问题 -- 生产者 消费者

    工作2年多来一直也没有计划写自己的技术博客,最近辞职在家翻看<thingking in JAVA>,偶尔看到了生产者与消费者的一个经典的多线程同步问题.本人在工作中很少使用到多线程以及高并 ...

  6. c++并发练习---生产者消费者模型

    问题:有一个生产者,多个消费者,生产者每生产一个,放入队列,多个消费者顺序从队列中取出数据,打印最终结果. 分析:首先这题,我本意应该设计成如下模型:生产者单开一个线程,向队列中放入数据,而消费者在锁 ...

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

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

  8. JAVA多线程经典问题 -- 生产者 消费者 同步队列实现方法

    在JAVASE5 中的java.util.concurrent.BlockingQueue支持,BlockingQueue是一个接口但是我们通常可以使用LinkedBlockingQueue,它是一个 ...

  9. 【收藏】Java多线程/并发编程大合集

    (一).[Java并发编程]并发编程大合集-兰亭风雨    [Java并发编程]实现多线程的两种方法    [Java并发编程]线程的中断    [Java并发编程]正确挂起.恢复.终止线程    [ ...

随机推荐

  1. 关于Integer的比较,今天又犯了一个低级错误,记录下

    今天查看以前所写的代码,看到有一部分被人改了,代码如下: if (orgId != organizationUpdateReq.getOrgId()) { //orgId的类型为Integer,org ...

  2. Haskell语言学习笔记(25)MonadState, State, StateT

    MonadState 类型类 class Monad m => MonadState s m | m -> s where get :: m s get = state (\s -> ...

  3. git 拉取某个分支到本地

    git 拉取其实只需要 git fetch origin xxx. git pull origin xxx即可

  4. Ubuntu 安装 Zabbix 3.2详细步骤

    创建 zabbix 用户 因为zabbix 程序的守护进程需要非特权用户,所以需要创建一个 zabbix 用户,即使从 root 用户启动 zabbix 程序,也会自动切换到 zabbix 用户,所以 ...

  5. 关于使用service的上下文和activity来读取sharedpreferences的同步问题

    比如我用activity 对象 mainactivity 的context 获取了sharedpreferences对象,并putString(context, "demo", & ...

  6. mysql for update语句

    我们都知道for update语句会锁住一张表,锁表的细节很多人却不太清楚,下面我们举例看下. 在表上我们有个索引,如下: 现在在我们通过索引store_id锁表: 我们再开一个客户端,还是锁住同一个 ...

  7. OpenOffice Word文档转换成Html格式

    为什么会想起来将上传的word文档转换成html格式呢?设想,如果一个系统需要发布在页面的文章都是来自word文档,一般会执行下面的流程:使用word打开文档,Ctrl+A,进入发布文章页面,Ctrl ...

  8. __init__和__new__,以及self

    __new__: 每次实例化类的时候会默认先执行__new__,进行实例化类. 如果想改变默认__new__行为,可以对它进行自定义,必须有返回实例.   __init__: 对实例化的类进行初始化, ...

  9. 42-python中的矩阵、多维数组----numpy

    xzcfightingup   python中的矩阵.多维数组----numpy 1. 引言 最近在将一个算法由matlab转成python,初学python,很多地方还不熟悉,总体感觉就是上手容易, ...

  10. apache中开启rewrite

    1.在apache配置文件httpd.conf中找到如下行: #LoadModule rewrite_module modules/mod_rewrite.so 去掉该行前面的#号 2.在httpd. ...