Что мы должны сделать, чтобы преодолеть livelock? (в целом и специфично для примера кода, приведенного ниже)
Я новичок в Java и пытаюсь изучить концепцию livelock.
Я нашел отличный пример онлайн-блокировки, когда муж и жена пытаются есть суп, но между ними только одна ложка. Каждый из супругов слишком вежлив, и передаст ложку, если другой еще не ел.
Мой вопрос заключается в том, что мы должны сделать, чтобы преодолеть проблему livelock в целом, и в этом конкретном примере? Я хочу изменить свой код, чтобы продемонстрировать решение проблемы.
public class Livelock {
static class Spoon {
private Diner owner;
public Spoon(Diner d) { owner = d; }
public Diner getOwner() { return owner; }
public synchronized void setOwner(Diner d) { owner = d; }
public synchronized void use() {
System.out.printf("%s has eaten!", owner.name);
}
}
static class Diner {
private String name;
private boolean isHungry;
public Diner(String n) { name = n; isHungry = true; }
public String getName() { return name; }
public boolean isHungry() { return isHungry; }
public void eatWith(Spoon spoon, Diner spouse) {
while (isHungry) {
// Don't have the spoon, so wait patiently for spouse.
if (spoon.owner != this) {
try { Thread.sleep(1); }
catch(InterruptedException e) { continue; }
continue;
}
// If spouse is hungry, insist upon passing the spoon.
if (spouse.isHungry()) {
System.out.printf(
"%s: You eat first my darling %s!%n",
name, spouse.getName());
spoon.setOwner(spouse);
continue;
}
// Spouse wasn't hungry, so finally eat
spoon.use();
isHungry = false;
System.out.printf(
"%s: I am stuffed, my darling %s!%n",
name, spouse.getName());
spoon.setOwner(spouse);
}
}
}
public static void main(String[] args) {
final Diner husband = new Diner("Bob");
final Diner wife = new Diner("Alice");
final Spoon s = new Spoon(husband);
new Thread(new Runnable() {
public void run() { husband.eatWith(s, wife); }
}).start();
new Thread(new Runnable() {
public void run() { wife.eatWith(s, husband); }
}).start();
}
}
1 ответ
В общем, универсального решения для livelock не существует.
Поток должен прекратить повторять те же действия, если прогресс не был обнаружен.
В вашем примере, позволяя супругу есть больше одного раза (таким образом обнаруживая, что близкий человек не ел и никакого прогресса не было достигнуто, поскольку прием пищи занимает всего 1 шаг), вынудите владельца ложки просто есть.
Очевидно, что сценарии реальной жизни будут более сложными, но крайне важно обнаружить нулевой прогресс и действовать иначе, чем обычно.