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

上一讲我们让消费者和生产者都各停1毫秒,实际上大多并不是这样的。第二讲,我们讲一个极端的例子和一个正常的例子,假设您已经看过上一讲,我们只改变Consumer和Producer,来看结果。

Java生产者与消费者(上)

名词解释

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:1
Produce1 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生产者与消费者(下)的更多相关文章

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

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 生产与消费者模式,是编程中最常用的模式之一,在多线程中应用比较明显.个人理解:在自助餐厅,厨师在不断 ...

  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. Windows下RabbitMQ 的下载、配置、Java实现生产者和消费者例子

    RabbitMQ是一个轻量级的消息代理中间件,支持多种消息通信协议,支持分布式部署,支持运行于多个操作系统,具有灵活.高可用等特性.RabbitMQ支持多种协议,其中最为重要的是高级消息队列协议(AM ...

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

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

  9. Java实现生产者和消费者

    生产者和消费者问题是操作系统的经典问题,在实际工作中也常会用到,主要的难点在于协调生产者和消费者,因为生产者的个数和消费者的个数不确定,而生产者的生成速度与消费者的消费速度也不一样,同时还要实现生产者 ...

随机推荐

  1. [HNOI2004]高精度开根

    题目:洛谷P2293.BZOJ1213. 题目大意:给你$n,k(n\leq 10^{10000},k\leq 50)$,求$\lfloor \sqrt[k]{n}\rfloor$. 解题思路:高精度 ...

  2. 洛谷 P1020 导弹拦截 (LIS)

    第一问最长 不上升子序列,第二问最长上升子序列 套模板就好https://blog.csdn.net/qq_34416123/article/details/81358447 那个神奇的定理当作结论吧 ...

  3. 今日SGU 5.26

    #include<bits/stdc++.h> #define de(x) cout<<#x<<"="<<x<<endl ...

  4. [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 ...

  5. Light OJ 1341 Aladdin and the Flying Carpet

    题意:求大于b的a的因数对有几组.例10  2结果为{2,5},12 2结果为{2,6}{3,4}-----不反复 解一:分解质因数+DFS #include <iostream> #in ...

  6. 一张图片让你了解android的事件分发机制

  7. html关于不换行代码

    类似这种效果  这是基于a标签 不是用table实现的 <a style="display: inline-block;white-space:nowrap;width: 100px; ...

  8. 基于 Web 的 Go 语言 IDE - Wide 1.2.0 发布!

    Wide 是什么 Wide 是一个基于 Web 的 Go 语言团队 IDE. 在线开发:打开浏览器就可以进行开发.全快捷键 智能提示:代码自动完成.查看表达式.编译反馈.Lint 实时运行:极速编译. ...

  9. HTTP 与 HTTPS

    https就是http和TCP之间有一层SSL层,这一层的实际作用是防止钓鱼和加密. 防止钓鱼通过网站的证书,网站必须有CA证书,证书类似于一个解密的签名. 另外是加密,加密需要一个密钥交换算法,双方 ...

  10. C#一些延时函数

    sleep延时方法: System.Threading.Thread.Sleep(); //毫秒 在C#窗口程序中,如果在主线程里调用Sleep,在Sleep完成之前, 界面呈现出假死状态,不能响应任 ...