Java生产者与消费者(下)
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处!
上一讲我们让消费者和生产者都各停1毫秒,实际上大多并不是这样的。第二讲,我们讲一个极端的例子和一个正常的例子,假设您已经看过上一讲,我们只改变Consumer和Producer,来看结果。
名词解释
wait:当前线程不运行,处理等待状态,等待notify;所以也不会往下执行。
您可能会有疑问前例中的为什么要用while循环而非if语句?
主要是防止多线程操作时,例桌子已经占满,两个生产线程均处理等待状态,但消费线程通过notifyAll打开其等待状态,就造成生产过量的蛋糕,而导致生产消费模式失败,所以不能用if语句。
sleep:暂停当前线程若干时间,之后继续运行
Special Sample:生产者和消费者均不加sleep
Result:
Produce1 produce:1
Produce2 produce:2
Produce1 produce:3
Produce1 produce:4
Produce1 produce:5
Produce1 begin to wait !
Consumer1 consume:5
Consumer1 consume:4
Consumer1 consume:3
Consumer1 consume:2
Consumer1 consume:1
Consumer1 begin to wait !
Produce1 stop waiting !
Produce1 produce:1Produce1 produce:2
Produce2 produce:3
Produce2 produce:4
Produce2 produce:5
Produce2 begin to wait !
Consumer2 consume:5
Consumer2 consume:4
Consumer2 consume:3
Consumer2 consume:2
Consumer2 consume:1
Consumer2 begin to wait !
Produce2 stop waiting !
Produce2 produce:1
Produce2 produce:2
Produce2 produce:3
Produce2 produce:4
Produce2 produce:5
Produce2 begin to wait !
Produce1 begin to wait !
Consumer1 stop waiting !
Consumer1 consume:5
Consumer1 consume:4
Consumer1 consume:3
Consumer1 consume:2
Consumer1 consume:1
Consumer1 begin to wait !
Produce1 stop waiting !
Produce1 produce:1
Produce1 produce:2
Produce1 produce:3
Produce1 produce:4
Produce1 produce:5
Produce1 begin to wait !
Produce2 stop waiting !
Produce2 begin to wait !
Consumer2 stop waiting !
Consumer2 consume:5
Consumer2 consume:4
Consumer2 consume:3
Consumer2 consume:2
Consumer2 consume:1
Consumer2 begin to wait !
Produce2 stop waiting !
Produce2 produce:1
Produce2 produce:2
Produce2 produce:3
Produce2 produce:4
Produce2 produce:5
Produce2 begin to wait !
Produce1 stop waiting !
Produce1 begin to wait !
Consumer1 stop waiting !
Consumer1 consume:5
Consumer1 consume:4
Consumer1 consume:3
Consumer1 consume:2
Consumer1 consume:1
Consumer1 begin to wait !
Produce1 stop waiting !
Produce1 produce:1
Produce1 stop at last !解析:例子很极端,生产和消费均两个线程,A线程在工作时B在等待;
A生产线程生产,B生产线程等待直到A生产完;
A消费线程消费,B消费线程等待直到A消费完;
B生产线程生产,A生产线程等待直到A生产完;
B消费线程消费,A消费线程等待直到A消费完;……
这样一个循环,失去多线程的意义所在(变成了单线程)!
正常的例子:生产可能只需要1毫秒,消费需要2毫秒
Produce1 produce:1
Consumer1 consume:1
Consumer2 begin to wait !//此时Consumer2检测到count为0,所以等待
Produce2 produce:1
Consumer2 stop waiting !//此时Consumer2检测到count已经大于0,所以打开
Consumer2 consume:1
Produce1 produce:1//看,生产与消费是无序的。两者分开,不管你在不在生产,我都要消费,只要蛋糕还有;
Produce2 produce:2//不管你消费不消费,只要桌子还有空的;它们两个均对一种情况负责:桌子和蛋糕形成的映射关系!
Consumer2 consume:2
Consumer1 consume:1
Produce2 produce:1
Produce1 produce:2
Produce2 produce:3
Produce1 produce:4
Consumer1 consume:4
Consumer2 consume:3
Produce1 produce:3
Produce2 produce:4
Produce2 produce:5
Produce1 begin to wait !
Consumer1 consume:5
Produce1 stop waiting !
Produce1 produce:5
Produce2 begin to wait !
Consumer2 consume:5
Produce2 stop waiting !
Produce2 produce:5
Produce2 begin to wait !
Produce1 begin to wait !
Consumer2 consume:5
Produce1 stop waiting !
Produce1 produce:5
Produce2 stop waiting !
Produce2 begin to wait !
Consumer1 consume:5
Produce2 stop waiting !
Produce2 produce:5
Produce1 begin to wait !
Produce2 begin to wait !
Consumer1 consume:5
Consumer1 stop at last !解析:这次我让执行25次即退出虚拟机。
大家可以看到,本次两个生产线程和两个消费线程,在生产和消费的时候都是无序的,无论你要不要停,我都要工作,不能让一个线程一直抓住锁不放,其实这才是多线程本质。
代码如下:
Producer:
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();
}
}
}消费者:
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(2);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Java生产者与消费者(下)的更多相关文章
- Java生产者与消费者(上)
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 生产与消费者模式,是编程中最常用的模式之一,在多线程中应用比较明显.个人理解:在自助餐厅,厨师在不断 ...
- java生产者与消费者模式
前言: 生产者和消费者模式是我们在学习多线程中很经典的一个模式,它主要分为生产者和消费者,分别是两个线程, 目录 一:生产者和消费者模式简介 二:生产者和消费者模式的实现 声明:本例来源于java经典 ...
- java 生产者 与 消费者的案例
主要理解了两个问题 1.线程数据同步的问题 2.线程交替运行的方式 package ThreadDemo; /** * 生产者与消费者的案例(一,同步的问题,值的问题 二,交替执行的问题) * @au ...
- Java 生产者模式 消费者模式
// The standard idiom for calling the wait synchronized(sharedObject) { while(condition){ sharedObje ...
- Java生产者和消费者问题
容器类Box.java public class Box { private int num = 0; public void put(){ if(num==10){ try { System.out ...
- java生产者,消费者
有很多实现的方法 使用blockingqueue实现 demo import java.util.concurrent.LinkedBlockingQueue; /** * Created by 58 ...
- Windows下RabbitMQ 的下载、配置、Java实现生产者和消费者例子
RabbitMQ是一个轻量级的消息代理中间件,支持多种消息通信协议,支持分布式部署,支持运行于多个操作系统,具有灵活.高可用等特性.RabbitMQ支持多种协议,其中最为重要的是高级消息队列协议(AM ...
- java 生产者消费者问题 并发问题的解决
引言 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况: 生产者消费者图 ...
- Java实现生产者和消费者
生产者和消费者问题是操作系统的经典问题,在实际工作中也常会用到,主要的难点在于协调生产者和消费者,因为生产者的个数和消费者的个数不确定,而生产者的生成速度与消费者的消费速度也不一样,同时还要实现生产者 ...
随机推荐
- [HNOI2004]高精度开根
题目:洛谷P2293.BZOJ1213. 题目大意:给你$n,k(n\leq 10^{10000},k\leq 50)$,求$\lfloor \sqrt[k]{n}\rfloor$. 解题思路:高精度 ...
- 洛谷 P1020 导弹拦截 (LIS)
第一问最长 不上升子序列,第二问最长上升子序列 套模板就好https://blog.csdn.net/qq_34416123/article/details/81358447 那个神奇的定理当作结论吧 ...
- 今日SGU 5.26
#include<bits/stdc++.h> #define de(x) cout<<#x<<"="<<x<<endl ...
- [Recompose] Compose Streams of React Props with Recompose’s compose and RxJS
Functions created with mapPropsStream canned be composed together to build up powerful streams. Brin ...
- Light OJ 1341 Aladdin and the Flying Carpet
题意:求大于b的a的因数对有几组.例10 2结果为{2,5},12 2结果为{2,6}{3,4}-----不反复 解一:分解质因数+DFS #include <iostream> #in ...
- 一张图片让你了解android的事件分发机制
- html关于不换行代码
类似这种效果 这是基于a标签 不是用table实现的 <a style="display: inline-block;white-space:nowrap;width: 100px; ...
- 基于 Web 的 Go 语言 IDE - Wide 1.2.0 发布!
Wide 是什么 Wide 是一个基于 Web 的 Go 语言团队 IDE. 在线开发:打开浏览器就可以进行开发.全快捷键 智能提示:代码自动完成.查看表达式.编译反馈.Lint 实时运行:极速编译. ...
- HTTP 与 HTTPS
https就是http和TCP之间有一层SSL层,这一层的实际作用是防止钓鱼和加密. 防止钓鱼通过网站的证书,网站必须有CA证书,证书类似于一个解密的签名. 另外是加密,加密需要一个密钥交换算法,双方 ...
- C#一些延时函数
sleep延时方法: System.Threading.Thread.Sleep(); //毫秒 在C#窗口程序中,如果在主线程里调用Sleep,在Sleep完成之前, 界面呈现出假死状态,不能响应任 ...