【发布时间】:2016-03-23 03:37:34
【问题描述】:
我已经做了一个等待和通知示例程序,它是蛋糕店的抽象。有一个带有角色蛋糕机的线程用于生产蛋糕,一个带有角色服务员的线程用于交付蛋糕。我的期望是每次CakeMachine 类完成制作蛋糕时,它会向Waiter 类发送通知以进行交付。当我运行一个生产 3 个蛋糕的程序时,结果显示只交付了一个蛋糕。这是我的代码:
用于创建蛋糕对象的Cake 类:
class Cake {
private int weight;
private String color;
public Cake(int weight, String color) {
this.weight = weight;
this.color = color;
}
public String toString(){
return "The cake is in " + color +" and is " + weight + " gram ";
}
}
用于制作蛋糕的CakeMachine 类:
class CakeMachine implements Runnable{
private List<Cake> listCake;
CakeMachine(List<Cake> listCake) {
this.listCake = listCake;
}
public void makeCake() {
int weight = new Random().nextInt(20);
Cake cake = new Cake(weight, "color code is " + weight );
listCake.add(cake);
System.out.println("cake has been cooked ");
listCake.notify();
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
synchronized (listCake) {
makeCake();
}
}
}
}
Waiter 送蛋糕类:
class Waiter implements Runnable {
private List<Cake> listCake;
Waiter(List<Cake> listCake) {
this.listCake = listCake;
}
public void delivery() {
System.out.println("Waiter is waiting for the cake ");
try {
listCake.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
Cake cake = listCake.get(listCake.size() - 1);
System.out.println(cake.toString() + "has been delivered to customers ");
}
@Override
public void run() {
for (int i = 0; i < 3; i++)
{
synchronized (listCake) {
delivery();
}
}
}
}
还有主类:
public class WaitAndNotify {
public static List<Cake> listCake = new ArrayList<>();
public static void main(String[] args) {
Thread waiter = new Thread(new Waiter(listCake));
Thread cakeMachine = new Thread(new CakeMachine(listCake));
waiter.start();
cakeMachine.start();
}
}
运行程序的结果是:
Waiter is waiting for the cake
cake has been cooked
cake has been cooked
cake has been cooked
The cake is in color code is 18 and is 18 gram has been delivered to customers
Waiter is waiting for the cake
请帮助我了解这种情况。
【问题讨论】:
-
Effective Java Item 69: "很少有理由在新代码中使用
wait和notify。" -
你应该使用队列而不是列表,并使用并发包中的ConcurrentLinkedQueue来忽略多线程问题。
-
通知线程(在这种情况下为等待者)不会自动重新获取通知锁定。在通知之后,Waiter 和 CakeMachine 线程必须竞争锁,在您的情况下,CakeMachine 会获得锁。
标签: java multithreading wait synchronized notify