public class 包子笼 {
public int packNum = 100;
}
public class 吃包子的 extends Thread {
private 包子笼 p = null;
private String name;
public 吃包子的(包子笼 p, String name) {
this.p = p;
this.name = name;
}
//重写Thread里面的run方法(反复吃包子)
public void run() {
try {
while (true) {
synchronized (p) {
if (this.p.packNum <= 0) {//只要包子笼里面还有包子就继续吃,否则就退出
} else {
System.out.println(this.name + "吃第" + this.p.packNum + "个包子");
this.p.packNum--;
}
}
Thread.sleep(1);//控制当前线程休息,否则会一直执行当前线程
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class 做包子的 extends Thread {
private 包子笼 p = null;
private String name = null;//做包子的人
public 做包子的(包子笼 p, String name) {
this.p = p;
this.name = name;
}
public void run(){
while (true){
synchronized (p) {
if(p.packNum <= 0){
p.packNum = 100;
System.out.println(this.name + "做好了" + p.packNum + "个包子");
}else {
}
}
}
}
}
public class 测试吃包子 {
public static void main(String[] args) {
包子笼 p = new 包子笼();
做包子的 z = new 做包子的(p,"李厨");
吃包子的 e = new 吃包子的(p,"小常");
吃包子的 e1 = new 吃包子的(p,"小方");
z.start();
e.start();
e1.start();
}
}
这样做表面上看是没有问题的,但实际上中间浪费了大量的时间,因为吃包子的人当没有包子的时候,消费者什么也没做,此时就会浪费掉自己大量的时间;同样,生产者包子提前做完了,他也什么都不做,而他自己剩下的时间呀会浪费掉。
解决方法:
public void run(){
try {
while (true){
synchronized (p) {
if(p.packNum <= 0){
p.packNum = 100;
System.out.println(this.name + "做好了" + p.packNum + "个包子");
}else {
p.notifyAll();//先唤醒别人吃包子
p.wait();//然后自己再休息
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
try {
while (true) {
synchronized (p) {
if (this.p.packNum <= 0) {//只要包子笼里面还有包子就继续吃,否则就退出
//唤醒做包子的人,之后再把自己放进线程等待队列里面
p.notifyAll();
//只要放进线程等待队列里面,线程会自动释放掉
p.wait();//当包子吃完没事做的时候,就让他休息一会,同时释放掉自己的时间
} else {
System.out.println(this.name + "吃第" + this.p.packNum + "个包子");
this.p.packNum--;
}
}
Thread.sleep(1);//控制当前线程休息,否则会一直执行当前线程
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}