1.  

本文来自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 {

  1. private volatile int count;
  2. private int cake;
  3. private int stopCounts;
  4.  
  5. public Table(int count) {
  6. // TODO Auto-generated constructor stub
  7. this.count = count;
  8. }
  9.  
  10. public synchronized void produce(String threadName) throws InterruptedException {
  11. while (cake >= count) {
  12. System.out.println(threadName + " begin to wait !");
  13. wait();
  14. System.out.println(threadName + " stop waiting !");
  15. }
  16. System.out.println(threadName + " produce:" + ++cake);
  17. notifyAll();
  18. if (++stopCounts > 50) {
  19. System.out.println(threadName + " stop at last !");
  20. System.exit(0);
  21. }
  22. }
  23.  
  24. public synchronized void consume(String threadName) throws InterruptedException {
  25. while (cake <= 0) {
  26. System.out.println(threadName + " begin to wait !");
  27. wait();
  28. System.out.println(threadName + " stop waiting !");
  29.  
  30. }
  31. System.out.println(threadName + " consume:" + cake--);
  32. notifyAll();
  33.  
  34. if (++stopCounts > 50) {
  35. System.out.println(threadName + " stop at last !");
  36. System.exit(0);
  37. }
  38. }
  39. }

生产者:

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

  1. public class Producer extends Thread {
  2. Table table;
  3. String threadName;
  4.  
  5. public Producer(String string, Table table) {
  6. // TODO Auto-generated constructor stub
  7. this.table = table;
  8. this.threadName=string;
  9. this.setName(threadName);
  10. }
  11.  
  12. @Override
  13. public void run() {
  14. // TODO Auto-generated method stub
  15. super.run();
  16. try {
  17. while (true) {
  18. table.produce(threadName);
  19. sleep(1);
  20. }
  21. } catch (InterruptedException e) {
  22. // TODO Auto-generated catch block
  23. e.printStackTrace();
  24. }
  25. }
  26. }

消费者:

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

  1. public class Consumer extends Thread {
  2. Table table;
  3. String threadName;
  4.  
  5. public Consumer(String string, Table table) {
  6. // TODO Auto-generated constructor stub
  7. this.table = table;
  8. this.threadName=string;
  9. this.setName(threadName);
  10. }
  11.  
  12. @Override
  13. public void run() {
  14. // TODO Auto-generated method stub
  15. super.run();
  16. try {
  17. while (true) {
  18. table.consume(threadName);
  19. sleep(1);
  20. }
  21. } catch (InterruptedException e) {
  22. // TODO Auto-generated catch block
  23. e.printStackTrace();
  24. }
  25. }
  26. }

验证程序:

多线程

  1. public class TestCP {
  2. public static void main(String[] args) {
  3. Table table = new Table(5);
  4. Thread p1 = new Producer("Produce1",table);
  5. Thread c1 = new Consumer("Consumer1",table);
  6. Thread p2 = new Producer("Produce2",table);
  7. Thread c2 = new Consumer("Consumer2",table);
  8. p1.start();
  9. c1.start();
  10. p2.start();
  11. c2.start();
  12. }
  13. }

验证结果:

  1. Produce1 produce:1 //Producer1先生产一只cake
  2. Produce2 produce:2 //Producer2得到锁生产一只
  3. Consumer1 consume:2 //Consumer1先消费一只
  4. Consumer2 consume:1 //Consumer2得到锁也消费一只
  5. Consumer1 begin to wait ! //Consumer1得到锁开始等待
  6. Produce1 produce:1 //Producer1开始生产
  7. Produce2 produce:2 // Producer2开始生产
  8. Consumer2 consume:2 //Consumer2开始消费
  9. Consumer1 stop waiting ! //当cake数大于0,Consumer1停止等待
  10. Consumer1 consume:1 //Consumer1开始消费
  11. Consumer1 begin to wait ! //当cake数等于0,Consumer1开始等待
  12. Consumer1 consume:1 //Consumer1开始消费
  13. Consumer1 begin to wait ! //当cake数等于0,Consumer1开始等待
  14. Produce2 produce:1 //..............................
  15. Consumer1 stop waiting !
  16. Consumer1 consume:1
  17. Produce1 produce:1
  18. Consumer2 consume:1
  19. Consumer1 begin to wait !
  20. Consumer2 begin to wait !
  21. Produce1 produce:1
  22. Produce2 produce:2
  23. Consumer2 stop waiting !
  24. Consumer2 consume:2
  25. Consumer1 stop waiting !
  26. Consumer1 consume:1
  27. Consumer2 begin to wait !
  28. Consumer1 begin to wait !
  29. Produce1 produce:1
  30. Consumer1 stop waiting !
  31. Consumer1 consume:1
  32. Consumer2 stop waiting !
  33. Consumer2 begin to wait !
  34. Produce2 produce:1
  35. Consumer2 stop waiting !
  36. Consumer2 consume:1
  37. Consumer2 begin to wait !
  38. Produce1 produce:1
  39. Consumer1 consume:1
  40. Consumer2 stop waiting !
  41. Consumer2 begin to wait !
  42. Produce2 produce:1
  43. Consumer2 stop waiting !
  44. Consumer2 consume:1
  45. Produce1 produce:1
  46. Produce2 produce:2
  47. Consumer2 consume:2
  48. Consumer1 consume:1
  49. Consumer1 begin to wait !
  50. Consumer2 begin to wait !
  51. Produce1 produce:1
  52. Produce2 produce:2
  53. Consumer2 stop waiting !
  54. Consumer2 consume:2
  55. Consumer1 stop waiting !
  56. Consumer1 consume:1
  57. Consumer1 begin to wait !
  58. Produce2 produce:1
  59. Produce1 produce:2
  60. Consumer1 stop waiting !
  61. Consumer1 consume:2
  62. Consumer2 consume:1
  63. Consumer1 begin to wait !
  64. Produce1 produce:1
  65. Consumer2 consume:1
  66. Produce2 produce:1
  67. Consumer1 stop waiting !
  68. Consumer1 consume:1
  69. Consumer2 begin to wait !
  70. Consumer1 begin to wait !
  71. Produce1 produce:1
  72. Consumer1 stop waiting !
  73. Consumer1 consume:1
  74. Consumer2 stop waiting !
  75. Consumer2 begin to wait !
  76. Produce2 produce:1
  77. Consumer2 stop waiting !
  78. Consumer2 consume:1
  79. Consumer2 begin to wait !
  80. Produce2 produce:1
  81. Produce1 produce:2
  82. Consumer1 consume:2
  83. Consumer2 stop waiting !
  84. Consumer2 consume:1
  85. Consumer1 begin to wait !
  86. Produce2 produce:1
  87. Consumer1 stop waiting !
  88. Consumer1 consume:1
  89. Consumer2 begin to wait !
  90. Produce1 produce:1
  91. 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. Android 查看CPU及内存

    借助getprop.dumpsys来了解一些系统相关信息. 一.getprop adb shell cat /system/build.prop 文件中存放的是用于启动系统时需要的配置文件,通常可以通 ...

  2. spring的PropertyPlaceholderConfigurer不生效的问题

    经常出现这种问题,每次都debug知道原因,但每次都会忘记,所以记录一下. 原因:maven项目中使用了非maven管理的jar包(通过systemPath引用),这些jar包没有放在${projec ...

  3. Light oj 1138 - Trailing Zeroes (III) 【二分查找好题】【 给出N!末尾有连续的Q个0,让你求最小的N】

    1138 - Trailing Zeroes (III) PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 ...

  4. Java接口源码--System和应用程序进程间通信

    本文參考<Android系统源代码情景分析>.作者罗升阳 一.架构代码: ~/Android/frameworks/base/core/java/android/os ----IInter ...

  5. JNI学习积累之三 ---- 操作JNI函数以及复杂对象传递

    本文原创,转载请注明出处:http://blog.csdn.NET/qinjuning 在掌握了JNI函数的使用和相关类型的映射后,以及知晓何利用javah工具生成对应的jni函数以及如何生成动态 链 ...

  6. 118.类包装器与lambda函数包装器(伪函数实现)

    #include <iostream> #include <list> using namespace std; //函数包装器,左边参数右边函数 template<cl ...

  7. LINQ的基本语法包含如下的8个上下文关键字,这些关键字和具体的说明如下

    出于工作需要,准备把LINQ的相关知识梳理一遍,希望能填补下之前学习漏掉的或是没有注意的地方,也为未来减轻压力~ LINQ查询表达式的基本语法很容易掌握,它使用C#常见的语言构造,从外观上看,和我们常 ...

  8. C#初学者使用file.creat()创建文件后,显示正由另一进程使用

    string sourcePhotoPath = this.GetUserSelectedPhoto(); if(sourcePhotoPath == null) { return; } string ...

  9. AtCoder Beginner Contest 067 C - Splitting Pi

    C - Splitting Pile Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement Snu ...

  10. Hi3531D搭建环境时,出现的问题

    1.展开SDK包得时候,运行./sdk.unpack得时候出现: 原因:ubuntu14.04中默认得是dash,要将dash改成bash. 解决方法:sudo ln -fs /bin/bash /b ...