package com.produce;

import java.util.LinkedList;
import java.util.Queue; /*@author shijin
* 生产者与消费者模型中,要保证以下几点:
* 1 同一时间内只能有一个生产者生产 生产方法加锁sychronized
* 2 同一时间内只能有一个消费者消费 消费方法加锁sychronized
* 3 生产者生产的同时消费者不能消费 生产方法加锁sychronized
* 4 消费者消费的同时生产者不能生产 消费方法加锁sychronized
* 5 共享空间空时消费者不能继续消费 消费前循环判断是否为空,空的话将该线程wait,释放锁允许其他同步方法执行
* 6 共享空间满时生产者不能继续生产 生产前循环判断是否为满,满的话将该线程wait,释放锁允许其他同步方法执行
*/ //主类
public class ProducerConsumer
{
public static void main(String[] args)
{
StackBasket s = new StackBasket();
Producer p = new Producer(s);
Consumer c = new Consumer(s);
Thread tp = new Thread(p);
Thread tc = new Thread(c);
tp.start();
tc.start();
}
} /**
* 馒头
* */
class Mantou
{
private int id; Mantou(int id){
this.id = id;
} public String toString(){
return "馒头ID" + id;
}
} /**
* 共享栈空间 仓库
* */
class StackBasket
{
Queue<Mantou> sm = new LinkedList<Mantou>();
int index = 6; /**
* show 生产方法.
* show 该方法为同步方法,持有方法锁;
* show 首先循环判断满否,满的话使该线程等待,释放同步方法锁,允许消费;
* show 当不满时首先唤醒正在等待的消费方法,但是也只能让其进入就绪状态,
* show 等生产结束释放同步方法锁后消费才能持有该锁进行消费
* @param m 元素
* @return 没有返回值
*/ public synchronized void push(Mantou m){
try{
while(index == sm.size()){
System.out.println("!!!!!!!!!生产满了!!!!!!!!!");
this.wait();
}
this.notify();
}catch(InterruptedException e){
e.printStackTrace();
}catch(IllegalMonitorStateException e){
e.printStackTrace();
}
//此处可执行逻辑操作,如从数据库取出数据
sm.offer(m);
System.out.println("生产了:" + m + " 仓库有:" + sm.size() + "个馒头");
} /**
* show 消费方法
* show 该方法为同步方法,持有方法锁
* show 首先循环判断空否,空的话使该线程等待,释放同步方法锁,允许生产;
* show 当不空时首先唤醒正在等待的生产方法,但是也只能让其进入就绪状态
* show 等消费结束释放同步方法锁后生产才能持有该锁进行生产
* @param b true 表示显示,false 表示隐藏
* @return 没有返回值
*/
public synchronized Mantou pop(){
try{
while(sm.size() == 0){
System.out.println("!!!!!!!!!消费光了!!!!!!!!!");
this.wait();
}
this.notify();
}catch(InterruptedException e){
e.printStackTrace();
}catch(IllegalMonitorStateException e){
e.printStackTrace();
}
Mantou mantou=sm.poll();
     //此处可执行逻辑代码,如将数据更新回数据库
System.out.println("消费了:" + mantou + " 仓库有:" + sm.size() + "个馒头");  
return mantou;
}
} /**
* 生产者
* */
class Producer implements Runnable
{
StackBasket ss = new StackBasket();
Producer(StackBasket ss){
this.ss = ss;
} /**
* show 生产进程.
*/
public void run(){
for(int i = 0;i < 20;i++){
Mantou m = new Mantou(i);
ss.push(m);
// System.out.println("生产了:" + m + " 共" + ss.index + "个馒头");
// 在上面一行进行测试是不妥的,对index的访问应该在原子操作里,因为可能在push之后此输出之前又消费了,会产生输出混乱
try{
Thread.sleep((int)(Math.random()*500));
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
} /**
* 消费者
* */
class Consumer implements Runnable
{
StackBasket ss = new StackBasket();
Consumer(StackBasket ss){
this.ss = ss;
} /**
* show 消费进程.
*/
public void run(){
for(int i = 0;i < 20;i++){
Mantou m = ss.pop();
//System.out.println("消费了:---------" + m + " 共" + ss.index + "个馒头");
//同上 在上面一行进行测试也是不妥的,对index的访问应该在原子操作里,因为可能在pop之后此输出之前又生产了,会产生输出混乱
try{
Thread.sleep((int)(Math.random()*1000));
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}

输出结果:

!!!!!!!!!消费光了!!!!!!!!!
生产了:馒头ID0 仓库有:1个馒头
消费了:馒头ID0 仓库有:0个馒头
生产了:馒头ID1 仓库有:1个馒头
生产了:馒头ID2 仓库有:2个馒头
生产了:馒头ID3 仓库有:3个馒头
消费了:馒头ID1 仓库有:2个馒头
生产了:馒头ID4 仓库有:3个馒头
消费了:馒头ID2 仓库有:2个馒头
生产了:馒头ID5 仓库有:3个馒头
消费了:馒头ID3 仓库有:2个馒头
生产了:馒头ID6 仓库有:3个馒头
生产了:馒头ID7 仓库有:4个馒头
生产了:馒头ID8 仓库有:5个馒头
消费了:馒头ID4 仓库有:4个馒头
生产了:馒头ID9 仓库有:5个馒头
生产了:馒头ID10 仓库有:6个馒头
!!!!!!!!!生产满了!!!!!!!!!
消费了:馒头ID5 仓库有:5个馒头
生产了:馒头ID11 仓库有:6个馒头
!!!!!!!!!生产满了!!!!!!!!!
消费了:馒头ID6 仓库有:5个馒头
生产了:馒头ID12 仓库有:6个馒头
!!!!!!!!!生产满了!!!!!!!!!
消费了:馒头ID7 仓库有:5个馒头
生产了:馒头ID13 仓库有:6个馒头
消费了:馒头ID8 仓库有:5个馒头
消费了:馒头ID9 仓库有:4个馒头
生产了:馒头ID14 仓库有:5个馒头
生产了:馒头ID15 仓库有:6个馒头
消费了:馒头ID10 仓库有:5个馒头
生产了:馒头ID16 仓库有:6个馒头
!!!!!!!!!生产满了!!!!!!!!!
消费了:馒头ID11 仓库有:5个馒头
生产了:馒头ID17 仓库有:6个馒头
!!!!!!!!!生产满了!!!!!!!!!
消费了:馒头ID12 仓库有:5个馒头
生产了:馒头ID18 仓库有:6个馒头
消费了:馒头ID13 仓库有:5个馒头
生产了:馒头ID19 仓库有:6个馒头
消费了:馒头ID14 仓库有:5个馒头
消费了:馒头ID15 仓库有:4个馒头
消费了:馒头ID16 仓库有:3个馒头
消费了:馒头ID17 仓库有:2个馒头
消费了:馒头ID18 仓库有:1个馒头
消费了:馒头ID19 仓库有:0个馒头

java之生产者与消费者的更多相关文章

  1. Windows下RabbitMQ 的下载、配置、Java实现生产者和消费者例子

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

  2. java实现生产者和消费者问题

    Java实现生产者和消费者问题 欢迎访问我的个人博客,获取更多有用的东西 链接一 链接二 也可以关注我的微信订阅号:CN丶Moti

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

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

  4. java线 生产者和消费者

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlhbmdydWkxOTg4/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  5. Java实现生产者与消费者模式

    生产者不断向队列中添加数据,消费者不断从队列中获取数据.如果队列满了,则生产者不能添加数据:如果队列为空,则消费者不能获取数据.借助实现了BlockingQueue接口的LinkedBlockingQ ...

  6. Java中生产者与消费者模式

    生产者消费者模式 首先来了解什么是生产者消费者模式.该模式也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例.该问题描述了两个共享固定大小缓冲区的线 ...

  7. java之生产者和消费者问题

    package testThread; public class Test3 { public static void main(String[] args) { Clerk c = new Cler ...

  8. 菜鸡的Java笔记 生产者与消费者

    生产者与消费者        代码要求知道做什么用即可        线程间的通讯问题以及 Object 类的支持            基础模型        现在希望实现一种数据的生产和取出的操作 ...

  9. Java 多线程-生产者、消费者

    一.整体代码 ThreadDemo.java public class ThreadDemo { public static void main(String[] args) { Godown god ...

随机推荐

  1. 斯坦福大学Andrew Ng教授主讲的《机器学习》公开课观后感[转]

    近日,在网易公开课视频网站上看完了<机器学习>课程视频,现做个学后感,也叫观后感吧. 学习时间 从2013年7月26日星期五开始,在网易公开课视频网站上,观看由斯坦福大学Andrew Ng ...

  2. Python字典笔记

    1.字典是Python中=唯一的映射类型.映射类型对象里哈希值(键,key)和只指向的对象(值,value)是一对多的关系,一个字典是可变的,是一个容器类型.字典类型和序列类型(元组,列表)的不同在于 ...

  3. 001. 启动Visual Studio 2010报错

    错误内容: 外接程序"VMDebugger"未能加载或导致了异常. 是否希望移除该外接程序? 错误号: 80004005 如下图: 解决办法一: 1. 点击 是 打开VS2010, ...

  4. 【转】SVN的UUID错误

    操作TortoiseSVN时,报如下错误:       Command Update       Repository UUID '62b86956-73d9-2945-ba87-0546d71898 ...

  5. EmEditor处理大文本文件

    前段时间新闻网由于用户不当操作.导致三年的报纸栏目内容全部清空.紧急情况下只能求助于SQL数据恢复.但备份的数据文件有500M左右. 首先用的文本编辑器是Notepad++,打开之后软件几乎完全卡死. ...

  6. R(二): http与R脚本通讯环境安装

    结合实际的工作环境,在开始R研究的时候,首先着手收集的就是能以Web方式发布R运行结果的基础框架,无耐的是,R一直以来常使用于个人电脑的客户端程序上,大家习惯性的下载R安装包,在自己的电脑上安装 -- ...

  7. TextArea限制输入长度

    cs文件中添加文本框属性this.TextBox.Attributes.Add("MaxLength", "200"); $(document).ready(f ...

  8. UI-动画

    // ------------------UIImageView的动画------------------ // ------------------UIView的动画---------------- ...

  9. Maven 依赖管理

    1  概念介绍 之前我们说过,maven 坐标能够确定一个项目.换句话说,我们可以用它来解决依赖关系.在 POM 中,依赖关系是在 dependencies部分中定义的.在上面的 POM 例子中,我们 ...

  10. Android中的布局优化方法

    http://blog.csdn.net/rwecho/article/details/8951009 Android开发中的布局很重要吗?那是当然.一切的显示样式都是由这个布局决定的,你说能不重要吗 ...