本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处!

生产与消费者模式,是编程中最常用的模式之一,在多线程中应用比较明显。个人理解:在自助餐厅,厨师在不断做菜放桌子上,吃货不断从桌子上拿东西,这中间如果桌子上已经摆满那厨师要暂停工作 ,桌子上已没有食物则吃货要暂停拿东西吃。

先决条件,食材充足,桌子一定。

本程序设计原则:由于synchronized加锁方法,使得内部的所有变量也被加锁;我们采取多线程操作,故中间要用sleep(为了把锁让给别人,比如A上厕所开启sleep模式,B就偷偷拿上锁溜进来,方便后再还锁给A,要保证B修改同一个资源的话,要在A sleep的时间内完成),以便其他线程可以使用(windows多线程亦采取同样设计原则),sleep很短的时间,故用户不会有停滞感。为结果清晰,producer和consumer共执行操作50次,则程序停止运行。

桌子:

count,即桌子数量一定,produce和consume均对count操作。当蛋糕数大于等于桌子数时,生产线程要等待;当蛋糕数少于或等于0时,消费线程要等待。notifyAll是唤醒所有线程,如果生产线程watit时,消费线程已经把cake吃光,则要唤醒生产线程,反之亦然,故用notifyAll,而notify仅唤醒当前线程,在这里是没有用的。

public class Table {

	private volatile int count;
private int cake;
private int stopCounts; public Table(int count) {
// TODO Auto-generated constructor stub
this.count = count;
} public synchronized void produce(String threadName) throws InterruptedException {
while (cake >= count) {
System.out.println(threadName + " begin to wait !");
wait();
System.out.println(threadName + " stop waiting !");
}
System.out.println(threadName + " produce:" + ++cake);
notifyAll();
if (++stopCounts > 50) {
System.out.println(threadName + " stop at last !");
System.exit(0);
}
} public synchronized void consume(String threadName) throws InterruptedException {
while (cake <= 0) {
System.out.println(threadName + " begin to wait !");
wait();
System.out.println(threadName + " stop waiting !"); }
System.out.println(threadName + " consume:" + cake--);
notifyAll(); if (++stopCounts > 50) {
System.out.println(threadName + " stop at last !");
System.exit(0);
}
}
}

生产者:

生产蛋糕,一次停止1毫秒

public class Producer extends Thread {
Table table;
String threadName; public Producer(String string, Table table) {
// TODO Auto-generated constructor stub
this.table = table;
this.threadName=string;
this.setName(threadName);
} @Override
public void run() {
// TODO Auto-generated method stub
super.run();
try {
while (true) {
table.produce(threadName);
sleep(1);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

消费者:

消费蛋糕,一次停止1毫秒

public class Consumer extends Thread {
Table table;
String threadName; public Consumer(String string, Table table) {
// TODO Auto-generated constructor stub
this.table = table;
this.threadName=string;
this.setName(threadName);
} @Override
public void run() {
// TODO Auto-generated method stub
super.run();
try {
while (true) {
table.consume(threadName);
sleep(1);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

验证程序:

多线程

public class TestCP {
public static void main(String[] args) {
Table table = new Table(5);
Thread p1 = new Producer("Produce1",table);
Thread c1 = new Consumer("Consumer1",table);
Thread p2 = new Producer("Produce2",table);
Thread c2 = new Consumer("Consumer2",table);
p1.start();
c1.start();
p2.start();
c2.start();
}
}

验证结果:

Produce1 produce:1            //Producer1先生产一只cake
Produce2 produce:2 //Producer2得到锁生产一只
Consumer1 consume:2 //Consumer1先消费一只
Consumer2 consume:1 //Consumer2得到锁也消费一只
Consumer1 begin to wait ! //Consumer1得到锁开始等待
Produce1 produce:1 //Producer1开始生产
Produce2 produce:2 // Producer2开始生产
Consumer2 consume:2 //Consumer2开始消费
Consumer1 stop waiting ! //当cake数大于0,Consumer1停止等待
Consumer1 consume:1 //Consumer1开始消费
Consumer1 begin to wait ! //当cake数等于0,Consumer1开始等待
Consumer1 consume:1 //Consumer1开始消费
Consumer1 begin to wait ! //当cake数等于0,Consumer1开始等待
Produce2 produce:1 //..............................
Consumer1 stop waiting !
Consumer1 consume:1
Produce1 produce:1
Consumer2 consume:1
Consumer1 begin to wait !
Consumer2 begin to wait !
Produce1 produce:1
Produce2 produce:2
Consumer2 stop waiting !
Consumer2 consume:2
Consumer1 stop waiting !
Consumer1 consume:1
Consumer2 begin to wait !
Consumer1 begin to wait !
Produce1 produce:1
Consumer1 stop waiting !
Consumer1 consume:1
Consumer2 stop waiting !
Consumer2 begin to wait !
Produce2 produce:1
Consumer2 stop waiting !
Consumer2 consume:1
Consumer2 begin to wait !
Produce1 produce:1
Consumer1 consume:1
Consumer2 stop waiting !
Consumer2 begin to wait !
Produce2 produce:1
Consumer2 stop waiting !
Consumer2 consume:1
Produce1 produce:1
Produce2 produce:2
Consumer2 consume:2
Consumer1 consume:1
Consumer1 begin to wait !
Consumer2 begin to wait !
Produce1 produce:1
Produce2 produce:2
Consumer2 stop waiting !
Consumer2 consume:2
Consumer1 stop waiting !
Consumer1 consume:1
Consumer1 begin to wait !
Produce2 produce:1
Produce1 produce:2
Consumer1 stop waiting !
Consumer1 consume:2
Consumer2 consume:1
Consumer1 begin to wait !
Produce1 produce:1
Consumer2 consume:1
Produce2 produce:1
Consumer1 stop waiting !
Consumer1 consume:1
Consumer2 begin to wait !
Consumer1 begin to wait !
Produce1 produce:1
Consumer1 stop waiting !
Consumer1 consume:1
Consumer2 stop waiting !
Consumer2 begin to wait !
Produce2 produce:1
Consumer2 stop waiting !
Consumer2 consume:1
Consumer2 begin to wait !
Produce2 produce:1
Produce1 produce:2
Consumer1 consume:2
Consumer2 stop waiting !
Consumer2 consume:1
Consumer1 begin to wait !
Produce2 produce:1
Consumer1 stop waiting !
Consumer1 consume:1
Consumer2 begin to wait !
Produce1 produce:1
Produce1 stop at last !

需要拓展知识的请关注:

Java生产者与消费者(下)

Java生产者与消费者(上)的更多相关文章

  1. Java生产者与消费者(下)

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 上一讲我们让消费者和生产者都各停1毫秒,实际上大多并不是这样的.第二讲,我们讲一个极端的例子和一个正 ...

  2. java生产者与消费者模式

    前言: 生产者和消费者模式是我们在学习多线程中很经典的一个模式,它主要分为生产者和消费者,分别是两个线程, 目录 一:生产者和消费者模式简介 二:生产者和消费者模式的实现 声明:本例来源于java经典 ...

  3. java 生产者 与 消费者的案例

    主要理解了两个问题 1.线程数据同步的问题 2.线程交替运行的方式 package ThreadDemo; /** * 生产者与消费者的案例(一,同步的问题,值的问题 二,交替执行的问题) * @au ...

  4. Java 生产者模式 消费者模式

    // The standard idiom for calling the wait synchronized(sharedObject) { while(condition){ sharedObje ...

  5. Java生产者和消费者问题

    容器类Box.java public class Box { private int num = 0; public void put(){ if(num==10){ try { System.out ...

  6. java生产者,消费者

    有很多实现的方法 使用blockingqueue实现 demo import java.util.concurrent.LinkedBlockingQueue; /** * Created by 58 ...

  7. java 生产者消费者问题 并发问题的解决

    引言 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况: 生产者消费者图 ...

  8. java生产者消费者并发协作

    随着职务转变,代码荒废很久了,很多时间都是在沟通需求,作为一名技术员,不写代码就感觉是在自废武功,慢慢颓废了很多,今天重新回顾了下JAVA线程知识,基础知识就不梳理了,网上也很多,主要关键几个状态位( ...

  9. java 生产者消费者问题 并发问题的解决(转)

    引言 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况: 生产者消费者图 ...

随机推荐

  1. 利用第三方类 phpmailer 发邮件

    第一.百度一下 phpmailer 随便找个 girhub 网站 download 下来即可. 第二.复制如下代码放在项目根目录,填写完整你的账号信息,即可发送邮件.就是这么简单! <?php ...

  2. NodeJS代码调试

    1.在Chrome打开chrome://flags/#enable-devtools-experiments 2.激活Developer Tools experiments 3.重启Chrome 4. ...

  3. 【Henu ACM Round#16 E】Paths and Trees

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 感觉很像一道最短路. 然后就试了一发. 结果真的是.. 只要用一个优先队列优化的dijkstra算法求出每个点的最短路上的前一个点是 ...

  4. Oracle拾遗

    这次学习Oracle视频.还是学到了不少东西的. 首先,这是一次系统的学习.对自己的知识体系是一次查漏补缺,曾经仅仅是简单的会用,如今看到出的问题,非常easy就能够想到是哪一部分出了问题.尤其是如今 ...

  5. CIKM 2013 Paper Modeling interaction features for debate side clustering

    中文简单介绍:本文对怎样对网上论坛讨论中用户交互关系进行统计建模分析进行了研究. 论文出处:CIKM'13. 英文摘要: Online discussion forums are popular so ...

  6. vue6 发请求

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. apiCloud手动检测更新

    有时候需要给用户一个自主的权利,自主检测app是否是最新版本. 如何实现? 1.点击调用接口,检测是否有更新. 默认APICloud会自动检测版本更新,用户也可以在config.xml里配置autoU ...

  8. Python正则表达式初识(三)

    前几天给大家分享了Python正则表达式基础(一)和Python正则表达式基础(二),感兴趣的小伙伴可以点击进去学习,今天继续给大家分享Python正则表达式基础. 1.正则表达式特殊字符“+”,其代 ...

  9. ES6学习基础

    1.let和const 与var不同,新的变量声明方式带来了一些不一样的特性,其中最重要的两个特性就是提供了块级作用域与不再具备变量提升 { let a = 20; } console.log(a); ...

  10. request.getSession().getServletContext().getRealPath("")获取工程目录 路径修改

    使用request.getSession().getServletContext().getRealPath("")获取工程目录. 设置server Locations在serve ...