java线程(三)生产者和消费者问题

 

一些人吃馒头,一些人拿馒头。抽象出来的对象:吃馒头的人,生产馒头的人,馒头,操作过程类。

 

  

 

 //模拟死锁。

 

public class  ProducerConsumer

{

 

public static void main(String[] args)

{

//执行这个过程。

SyncStack ss = new SyncStack();

//两个线程访问的是同一个篮子。

Producer p = new Producer(ss);

Consumer c = new Consumer(ss);

new Thread(p).start();

new Thread(c).start();

 

}

 

}

 class WoTou

 {

int id;

WoTou(int id)

{ this.id = id;}

 

//重写窝头的toString方法为了后面的打印。

public String toString()

{

return "wotou: " + id;

}

 }

 //用栈来描述篮子。

 

 class SyncStack

 {

//撞到第几个了。

int index = 0;

//装上六个。篮子最多装六个,如果篮子满了怎么办?

WoTou[] arrWT = new WoTou[6];

 

//往篮子里装窝头。

public synchronized void push(WoTou wt)

{        //如果当index还未来得及加的时候,就又仍入一个馒头。

//解决问题的办法就是在执行两句的时候不能被打断。所以我们加上做锁了。

//如果篮子满了怎么办?我们就让它休息了。

while(index == arrWT.length)

{                                    //当前的对象wait()当前的正在对象访问的线程wait()

try{

    this.wait();

} catch(InterruptedException e)

{

e.printStackTrace();

}

//和wait()对应。叫醒一个正在wait的线程。

}

this.notify();

arrWT[index] = wt;

index ++;

}

//为了在执行这个方法的时候不被打断出现的问题。

public synchronized WoTou pop()

{

//如果篮子已经是空的的了,没有馒头了,也需要等待。

while(index == 0)

{

//也让当前的线程wait()

try{

this.wait();

}

catch(InterruptedException e)

{

e.printStackTrace();

}

}

 

//叫醒当前对象的另一个线程。

this.notify();

index--;

return arrWT[index];

}

 

//会出现问题,wait()之后会死过去,这个锁不会归这个对象所有,wait()和sleep()的区别。

 

 

 }

 

 // 大师傅,在生产窝头。

 class Producer implements Runnable

 {

//放入那个篮子中。

SyncStack ss = null;

//构造方法来告诉我使用哪个篮子。

Producer(SyncStack ss)

{

this.ss = ss;

}

//生产馒头了。

public void run()

{

for(int i=0;i<20;i++)

{

WoTou wt = new WoTou(i);

//调用篮子的push方法,把馒头扔进去。

ss.push(wt);

//每生产一个就打印一个。

System.out.println("生产了" + wt );

//每生产一个我们就休息会儿。

ss.push(wt);

try

{

//睡眠一秒钟。

Thread.sleep((int)Math.random()*200);

}catch(InterruptedException e)

{

e.printStackTrace();

}

 

}

}

 

 }

 

 //做一个馒头的消费类。

 

 class Consumer implements Runnable

 {

//确定在哪个篮子里消费。

SyncStack ss = null;

//构造方法来告诉我使用哪个篮子。

Consumer(SyncStack ss)

{

this.ss = ss;

}

//生产馒头了。

public void run()

{

for(int i=0;i<20;i++)

{

WoTou wt = ss.pop();

System.out.println("消费了" + wt );

 

//每消费一个也睡眠一秒钟。

try

{

//睡眠一秒钟。

Thread.sleep((int)Math.random()*1000);

}catch(InterruptedException e)

{

e.printStackTrace();

}

 

 

}

}

 

 }

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值