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. Unity动画

    Unity 并没有自带建模工具. 3D建模工具 maya, 3dmax, blender Skinned Mesh Renderer Mesh Renderer Mesh Filter Modelli ...

  2. MySQL-负载很高排查思路

    工欲善其事必先利其器,我说一下思路 思路:1.确定高负载的类型 htop,dstat命令看负载高是CPU还是IO2.监控具体的sql语句,是insert update 还是 delete导致高负载3. ...

  3. int(M)与int

    int(M) ,加上zerofill后M才表现出有点效果,比如 int(3) zerofill,你插入到数据库里的是10,则实际插入为010,也就是在前面补充加了一个0.如果int(3)和int(10 ...

  4. 最大化 AIX 上的 Java 性能,第 4 部分: 监视流量

    http://www.ibm.com/developerworks/cn/aix/library/es-Javaperf/es-Javaperf4.html 最大化 AIX 上的 Java 性能,第 ...

  5. EDIUS分别输出视频和音频的教程

    使用EDIUS剪辑好视频之后渲染输出文件时,为什么视频和音频分别出,而不是一起呢?这个问题很可能会让一些新手困惑不已,到底是什么原因呢?又要如何设置才能让输出的文件视音频一体呢?下面,小编将来和大家探 ...

  6. .NET垃圾回收 – 非托管资源

    前面一篇文章介绍了垃圾回收的基本工作原理,垃圾回收器并不是可以管理内存中的所有资源.对于所有的托管资源都将有.NET垃圾回收机制来释放,但是,对于一些非托管资源,我们就需要自己编写代码来清理这类资源了 ...

  7. CSS3弹性盒模型之box-orient & box-direction

    Css3引入了新的盒模型——弹性盒模型,其实上一篇文章已经讲到了一个box-flex,今天来讲讲另外的两个弹性盒模型属性box-orient 和 box-direction. 1.box-origen ...

  8. linux包之dmidecode

    http://www.dmtf.org/standards/smbios Dmidecode 这款软件允许你在 Linux 系统下获取有关硬件方面的信息.Dmidecode 遵循 SMBIOS/DMI ...

  9. python3_RoboBrowser_test

    python3_RoboBrowser_test selenium库作为交互是非常方便的,但是却大大加长了加载的时间,例如需要渲染网址,加载js,造成在爬虫过程中时间变长. 因此找到一个虚拟的浏览器, ...

  10. iOS 下拉刷新和加载更多 (OC\Swift)

    Swift语言出来之后, 可能还没有第三方的下拉刷新和上提加载, 所以自己用UIRefreshControl控件和UITableView实例的tableFooterView(底部视图)属性结合起来写了 ...