您的位置:首页 > 编程语言 > Java开发

java线程通信--生产者消费者问题

2016-12-17 21:37 435 查看
我写了一个线程通信的小案例,贴出来,大家一起来讨论,如有不对之处,请大家指正,最后实现了顾客吃了一屉包子,通知商家做包子,包子做好了,通知顾客吃包子的效果。
package day21_Thread;
//放包子的笼屉
public class Basket {
private SteamedStuffedBun[] buns;
private boolean isEmpty;
public Basket(SteamedStuffedBun[] buns, boolean isEmpty) {
super();
this.buns = buns;
this.isEmpty = isEmpty;
}
public SteamedStuffedBun[] getBuns() {
return buns;
}
public void setBuns(SteamedStuffedBun[] buns) {
this.buns = buns;
}
public boolean isEmpty() {
return isEmpty;
}
public void setEmpty(boolean isEmpty) {
this.isEmpty = isEmpty;
}

}

package day21_Thread;
//生产者类
public class GouBuli implements Runnable {
private Basket basket; //一屉包子

public GouBuli(Basket basket) {
this.basket = basket;
}

@Override
public void run() {
while (true) {
synchronized (basket) {
if (!basket.isEmpty()) {
try {
basket.wait();//等待并且释放锁,当前线程处于阻塞状态(没权利枪CPU执行权),等待被唤醒,如果被唤醒后,且抢到了CPU资源,从这里开始继续执行
System.out.println("顾客通知(唤醒)我,表明没包子了,开始做包子");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for (int i = 0; i < basket.getBuns().length; i++) {
basket.getBuns()[i] = new SteamedStuffedBun("狗不理", "猪肉大葱", "蒸熟了");
}
System.out.println("一屉包子蒸好了");
basket.setEmpty(false);
basket.notify();//唤醒吃包子线程(不代表另一线程开始执行,只不过表明另一线程有了CPU执行权,处于就绪状态,抢到了CPU执行权,才可以执行)
//如果包子做好了,当前线程又抢到了CPU执行权,将处于阻塞状态,此时吃包子线程一定会抢到CPU执行权,吃完包子会唤醒当前线程,又开始做包子
}
//释放锁

}
}

}

package day21_Thread;
//消费者类
public class Customer implements Runnable {
private Basket basket;

public Customer(Basket basket) {
this.basket = basket;
}

@Override
public void run() {
while (true) {
synchronized (basket) {
if (basket.isEmpty()) {
try {
basket.wait();//等待并且释放锁(当前线程处于阻塞状态,等待被唤醒)
System.out.println("商家通知(唤醒)我,包子做好了,开始吃包子");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

for (SteamedStuffedBun bun : basket.getBuns()) {
System.out.println("顾客吃了一个狗不理包子");
}
System.out.println("顾客吃了一屉包子");
basket.setEmpty(true);
basket.notify();//唤醒蒸包子线程(*不代表另一个立马线程执行,释放锁后,线程处于就绪状态,仍然和另一线程争抢CPU资源)
//如果包子吃完了,当前线程又抢到了CPU资源,会进入阻塞状态,蒸包子线程一定会抢到CPU执行权,蒸完包子后,会唤醒当前线程,开始
//吃包子
}
}
}

}

package day21_Thread;
//生产者消费者问题小案例
public class ProducerConsumerTest {

public static void main(String[] args) {
Basket basket = new Basket(new SteamedStuffedBun[10],true);
GouBuli gouBuli = new GouBuli(basket);
Thread produceTh = new Thread(gouBuli,"生产线程");
Customer customer =new Customer(basket);
Thread cusumeTh = new Thread(customer,"消费线程");
produceTh.start();
cusumeTh.start();

}
}
执行结果:
一屉包子蒸好了

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一屉包子

顾客通知(唤醒)我,表明没包子了,开始做包子

一屉包子蒸好了

商家通知(唤醒)我,包子做好了,开始吃包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一屉包子

顾客通知(唤醒)我,表明没包子了,开始做包子

一屉包子蒸好了

商家通知(唤醒)我,包子做好了,开始吃包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一屉包子

顾客通知(唤醒)我,表明没包子了,开始做包子

一屉包子蒸好了

商家通知(唤醒)我,包子做好了,开始吃包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

顾客吃了一个狗不理包子

.......................................
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: