Ниже находится фрагмент кода из учебника "Философия Java". В нем кратко описывается концепция producer-consumer в многопоточности.
Общая суть такова, в ресторане (
Restaurant) есть один повар (
Chef) и один официант (WaitPerson). Официант ждет (
wait), пока повар приготовит блюдо (
Meal). Когда повар блюдо приготовил, он оповещает (
notify) об этом официанта, который получает блюдо, относит его клиенту и снова начинает ждать.
Подскажите пожалуйста, почему в качестве объекта для второго блока
synchronized, в котором находится метод
notifyAll() (например, это
rest.chef в классе
WaitPerson), используется не
this, как в первом случае? Есть идея, что это из-за того, что нужно разбудить именно повара, а не официанта, хочется развеять сомнения.
class WaitPerson implements Runnable {
private Restaurant rest;
public WaitPerson(Restaurant r) {
rest = r;
}
@Override
public void run() {
try {
while(!Thread.interrupted()) {
synchronized (this) {
while (rest.meal == null)
wait(); // ... for the chef to produce a meal
}
System.out.println("Waitperson got " + rest.meal);
synchronized (rest.chef) {
rest.meal = null;
rest.chef.notifyAll(); // ready for another
}
}
} catch(InterruptedException e) {
System.out.println("WaitPerson interrupted");
}
}
}
class Chef implements Runnable {
private Restaurant rest;
private int count = 0;
public Chef(Restaurant r) {
rest = r;
}
@Override
public void run() {
try {
while(!Thread.interrupted()) {
synchronized (this) {
while(rest.meal != null)
wait(); // ... for the meal to be taken
}
if(++count == 10) {
System.out.println("Out of food");
rest.exec.shutdownNow();
}
System.out.print("Order up! ");
synchronized (rest.waitPerson) {
rest.meal = new Meal(count);
rest.waitPerson.notifyAll();
}
TimeUnit.MILLISECONDS.sleep(100);
}
} catch(InterruptedException e) {
System.out.println("Chef interrupted");
}
}
}