生产者与消费者 java_java之生产者与消费者

packagecom.produce;importjava.util.LinkedList;importjava.util.Queue;/*@author shijin

* 生产者与消费者模型中,要保证以下几点:

* 1 同一时间内只能有一个生产者生产 生产方法加锁sychronized

* 2 同一时间内只能有一个消费者消费 消费方法加锁sychronized

* 3 生产者生产的同时消费者不能消费 生产方法加锁sychronized

* 4 消费者消费的同时生产者不能生产 消费方法加锁sychronized

* 5 共享空间空时消费者不能继续消费 消费前循环判断是否为空,空的话将该线程wait,释放锁允许其他同步方法执行

* 6 共享空间满时生产者不能继续生产 生产前循环判断是否为满,满的话将该线程wait,释放锁允许其他同步方法执行*/

//主类

public classProducerConsumer

{public static voidmain(String[] args)

{

StackBasket s= newStackBasket();

Producer p= newProducer(s);

Consumer c= newConsumer(s);

Thread tp= newThread(p);

Thread tc= newThread(c);

tp.start();

tc.start();

}

}/*** 馒头

**/

classMantou

{private intid;

Mantou(intid){this.id =id;

}publicString toString(){return "馒头ID" +id;

}

}/*** 共享栈空间 仓库

**/

classStackBasket

{

Queue sm = new LinkedList();int index = 6;/*** show 生产方法.

* show 该方法为同步方法,持有方法锁;

* show 首先循环判断满否,满的话使该线程等待,释放同步方法锁,允许消费;

* show 当不满时首先唤醒正在等待的消费方法,但是也只能让其进入就绪状态,

* show 等生产结束释放同步方法锁后消费才能持有该锁进行消费

*@paramm 元素

*@return没有返回值*/

public synchronized voidpush(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 等消费结束释放同步方法锁后生产才能持有该锁进行生产

*@paramb true 表示显示,false 表示隐藏

*@return没有返回值*/

public synchronizedMantou 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() + "个馒头");returnmantou;

}

}/*** 生产者

**/

class Producer implementsRunnable

{

StackBasket ss= newStackBasket();

Producer(StackBasket ss){this.ss =ss;

}/*** show 生产进程.*/

public voidrun(){for(int i = 0;i < 20;i++){

Mantou m= newMantou(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 implementsRunnable

{

StackBasket ss= newStackBasket();

Consumer(StackBasket ss){this.ss =ss;

}/*** show 消费进程.*/

public voidrun(){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();

}

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值