本文来自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. 20180929 北京大学 人工智能实践:Tensorflow笔记06

    入戏 需要修改成如下: (完)

  2. Zookeeper入门-Java版本HelloWorld例子

    上一篇介绍了,Zookeeper的基本概念,怎么启动,怎么解决可能遇到的几个问题.本篇,根据网上代码,整理了一个例子,Zookeeper的HelloWorld. 下面这个代码,还是比较简单的,核心类就 ...

  3. POJ——T 1986 Distance Queries

    http://poj.org/problem?id=1986 Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 14383   ...

  4. No enclosing instance of type E is accessible.

    No enclosing instance of type E  is accessible. 静态方法(main)中调用内部类,会出现这样的问题: 学习了:https://www.cnblogs.c ...

  5. Xcode加入应用图标以及启动界面

    寻找了许久的资料,记录下Xcode加入应用图标以及启动界面的学习笔记: 很实用的网址: 1.(苹果官网)Designing for iOS 2.iOS 8 人机交互指南 图标和图片的尺寸參考: 更加具 ...

  6. 融云消息接口apicloud

    融云提供消息发送服务,支持个人消息,群消息,讨论组,聊天室消息, 以下是它涉及到的接口. 初始化,连接之后,可以使用. <!DOCTYPE html> <html> <h ...

  7. Bundle捆绑压缩技术

    Bundle捆绑压缩技术由命名空间System.Web.Optimization中的类提供.顾名思义,这些类是用来优化Web页面性能的,它们通过压缩文件大小,捆绑文件(把多个文件合成一个下载文件)来实 ...

  8. HDU 5883 欧拉回路

    题面: 思路: 这里面有坑啊啊啊-.. 先普及一下姿势: 判断无向图欧拉路的方法: 图连通,只有两个顶点是奇数度,其余都是偶数度的. 判断无向图欧拉回路的方法: 图连通,所有顶点都是偶数度. 重点:图 ...

  9. HTML中常用的部分标签(一)

    [常见的块级标签] 标题标签<h1></h1>...<h6></h6> 水平线<hr/> 段落<p></p> 换行& ...

  10. cassandra install - +HeapDumpOnOutOfMemoryError -Xss180k

    原因分析: You are running out of allocted memory for the JAVA VM (128k) is to less. Modify the line belo ...