线程同步,使用 notifyAll()
Thread synchronizing, using notifyAll()
这是 Bruce Eckel 的 JAVA 第 3 版修订版 4.0 中第 13 章(练习 10)中的一个练习。我应该有一个 class 像厨师一样发出订单并通知服务员,还有两个服务员等待订单准备好,然后接受它。
这是我目前的情况:
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 到达他应该 wait() 的部分,直到他收到通知。然后我得到一个 IllegalMonitorStateException
,这意味着线程正在等待对象的监视器而不拥有指定的监视器。还是想不通。
您正在等待一个对象并通知另一个对象!
如果您在 Restaurant.waitpersonsList 上同步,那么您也需要等待它,而抛出异常的 wait() 试图等待 WaiterList 对象本身。
您的问题是您已经在 Restaurant.waitpersonsList 上进行了同步,但随后又在 WaitPerson 上调用了等待。您必须在
上调用 wait、notify 或 notifyAll 的任何对象上进行同步
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);
}
}
这是 Bruce Eckel 的 JAVA 第 3 版修订版 4.0 中第 13 章(练习 10)中的一个练习。我应该有一个 class 像厨师一样发出订单并通知服务员,还有两个服务员等待订单准备好,然后接受它。
这是我目前的情况:
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 到达他应该 wait() 的部分,直到他收到通知。然后我得到一个 IllegalMonitorStateException
,这意味着线程正在等待对象的监视器而不拥有指定的监视器。还是想不通。
您正在等待一个对象并通知另一个对象!
如果您在 Restaurant.waitpersonsList 上同步,那么您也需要等待它,而抛出异常的 wait() 试图等待 WaiterList 对象本身。
您的问题是您已经在 Restaurant.waitpersonsList 上进行了同步,但随后又在 WaitPerson 上调用了等待。您必须在
上调用 wait、notify 或 notifyAll 的任何对象上进行同步 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);
}
}