本文来自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生产者与消费者(下)

最新文章

  1. 利用matlab摄像机标定
  2. mysql分区表的原理和优缺点
  3. JS中innerHTML 和innerText和value的区别
  4. C# 文件流基本操作步骤
  5. heritrix 3.2.0 下载
  6. poj 1050 To the Max_dp求最大子矩阵和
  7. TCP的核心系列 — SACK和DSACK的实现(一)
  8. span标记
  9. Vue.js 插件开发详解
  10. canvas绘制一定数目的圆(均分)
  11. 小程序的get和post请求头的区别
  12. vim快捷键汇总
  13. @Autowired注解与@resource注解的区别(十分详细)
  14. Python中表达式与语句
  15. JVM 监控,调优,调试
  16. noi2017 day2t2
  17. [转]让Nginx支持ThinkPHP的URL重写和PATHINFO
  18. linux进程与线程的区别【转】
  19. MySQL数据库引擎、事务隔离级别、锁
  20. bzoj2750最短路计数

热门文章

  1. center os 7最小化安装后按table无法补全命令的问题
  2. python 进阶:修饰器的介绍
  3. 【DevExpress】GridControl添加按钮列并添加按钮事件
  4. Node.js的helloworld 程序
  5. Android Design Support Library(一)用TabLayout实现类似网易选项卡动态滑动效果
  6. Atcoder Grand Contest 107 A Biscuits
  7. GHO文件内IE主页的修改方法
  8. codeforces 140E.New Year Garland
  9. 今日SGU 5.18
  10. jQuery 判断是否包含在数组中 jQuery.inArray()