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实现生产者和消费者
生产者和消费者问题是操作系统的经典问题,在实际工作中也常会用到,主要的难点在于协调生产者和消费者,因为生产者的个数和消费者的个数不确定,而生产者的生成速度与消费者的消费速度也不一样,同时还要实现生产者 ...
随机推荐
- [POI2010]GIL-Guilds(结论题)
题意 给一张无向图,要求你用黑白灰给点染色,且满足对于任意一个黑点,至少有一个白点和他相邻:对于任意一个白点,至少有一个黑点与他相邻,对于任意一个灰点,至少同时有一个黑点和白点和灰点与他相邻,问能否成 ...
- Java web application——Listener
应用程序事件提供ServletContext和HttpSession以及ServletRequest对象状态更改的通知,用户编写响应状态更改的事件监听器类,并配置和部署他们.Servlet容器会调用事 ...
- Python组织文件 实践:查找大文件、 用Mb、kb显示文件尺寸 、计算程序运行时间
这个小程序很简单原本没有记录下来的必要,但在编写过程中又让我学到了一些新的知识,并且遇到了一些不能解决的问题,然后,然后就很有必要记录一下. 这个程序的关键是获取文件大小,本来用 os.path.ge ...
- JSunpack-n模拟WireShark拦截文件传输
前言: 在前面的实验里我们进行了JSunpack-n的安装及其简单使用.JSunpack-n还有另外一些功能须要进行測试试验,由于本人也是刚接触这些东西.本文就当中一个"功能点"进 ...
- xcode 4 svn配置(host is unreachable)
xcode 4 svn配置 先保证你的xcode中已经安装了command line tools xcode -> preferences -> downloads -> comma ...
- Python数据可视化——散点图
PS: 翻了翻草稿箱. 发现竟然存了一篇去年2月的文章...尽管naive.还是发出来吧... 本文记录了python中的数据可视化--散点图scatter, 令x作为数据(50个点,每一个30维), ...
- PHP从数组中删除元素的方法
PHP从数组中删除元素的方法 本篇文章主要介绍了PHP从数组中删除元素的四种方法实例 删除一个元素,且保持原有索引不变 使用 unset 函数,示例如下: 1 2 3 4 5 <?php $ ...
- 30.angularJS第一个实例
转自:https://www.cnblogs.com/best/tag/Angular/ AngularJS 通过 ng-directives 扩展了 HTML. ng-app 指令定义一个 Angu ...
- @Transactional 事务注解
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE, rollbackFor = ...
- POJ - 3842 An Industrial Spy dfs(水)
题意:给你一串数字,最少一个,最多七个,问用这里面的数字能组成多少素数,不重复. 思路:之前还遍历10000000的每一个素数,结果超时,后来发现直接dfs就可以了,只是标记一下做过的数. #prag ...