这是Bruce Eckel在JAVA第3版,修订版4.0,第13章(练习10)中的思考练习。我应该有一个类似于厨师的课程,它会发出命令并通知服务员,还有两个服务员等待订单准备好,然后接受它。
这是我到目前为止所拥有的:
class Order {
private static int i = 0;
private int count = i++;
public Order() {
if(count == 10) {
System.out.println("Out of food, closing.");
System.exit(0);
}
}
public String toString() {
return "Order " + count;
}
}
class WaitPerson extends Thread {
public Restaurant restaurant;
private int waitPersonId;
public WaitPerson(Restaurant r, int waitPersonId) {
restaurant = r;
this.waitPersonId = waitPersonId;
start();
}
public void run() {
Order currentOrder;
while(true) {
while(restaurant.order == null) {
synchronized(Restaurant.waitpersonsList) {
try {
System.out.println("Waitperson" + this.waitPersonId + " is waiting...");
wait();
System.out.println("WaitPerson" + this.waitPersonId + " is attempting to get " + restaurant.order);
}
catch(InterruptedException e) {
throw new RuntimeException(e);
}
}
}
currentOrder = restaurant.order;
System.out.println("Waitperson" + this.waitPersonId + " got " + currentOrder);
restaurant.order = null;
try {
sleep(3000); //waitperson is busy for 3 seconds
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Waitperson" + this.waitPersonId + " delivered " + currentOrder);
}
}
}
class Chef extends Thread {
private Restaurant restaurant;
private int ChefId;
public Chef(Restaurant r, int ChefId) {
restaurant = r;
this.ChefId = ChefId;
start();
}
public void run() {
while(true) {
if(restaurant.order == null) {
restaurant.order = new Order();
System.out.println("Chef" + this.ChefId + ": Order up! ");
synchronized(Restaurant.waitpersonsList) {
Restaurant.waitpersonsList.notifyAll();
}
}
try {
sleep(100);
}
catch(InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
class Restaurant {
public Order order;
public static List<WaitPerson> waitpersonsList = Collections.synchronizedList(new ArrayList<WaitPerson>());
}
public class Main {
public static void main(String[] args) {
Restaurant r = new Restaurant();
WaitPerson wp1 = new WaitPerson(r, 1);
WaitPerson wp2 = new WaitPerson(r, 1);
Restaurant.waitpersonsList.add(wp1);
Restaurant.waitpersonsList.add(wp2);
Chef chef = new Chef(r, 1);
}
}
一切正常,直到WaitPerson到达他应该等待的部分(),直到他得到通知。然后我得到一个IllegalMonitorStateException
,这意味着线程正在等待对象的监视器而不拥有指定的监视器。但是,无法解决这个问题。
答案 0 :(得分:2)
您正在等待一个物体并通知另一个物体!
如果你在Restaurant.waitpersonsList上同步,那么你也需要等待它,而抛出异常的wait()试图等待WaiterList对象本身。
答案 1 :(得分:2)
您的问题是您已经在Restaurant.waitpersonsList上进行了同步,但随后在WaitPerson上调用了wait。您必须在您调用wait,notify或notifyAll的任何对象上同步
ViewModel.DataLine