feat(concurrency): replace livelock example with corridor scenario

This commit is contained in:
user
2026-09-01 18:55:39 +04:00
parent cda58045bc
commit 4edbf2eb18
@@ -1,36 +1,99 @@
package com.example; package com.example;
import com.example.util.ThreadUtils;
public class LiveLock { public class LiveLock {
private static boolean thread1WantsToPass = true; static class Corridor {
private static boolean thread2WantsToPass = true; private Person currentPerson;
public Corridor(Person person) {
currentPerson = person;
}
public synchronized void setPerson(Person person) {
currentPerson = person;
}
public synchronized void pass() {
System.out.printf("%s прошёл по коридору!%n", currentPerson.name);
}
}
static class Person {
private String name;
private boolean wantsToPass;
public Person(String personName) {
name = personName;
wantsToPass = true;
}
public String getName() {
return name;
}
public boolean wantsToPass() {
return wantsToPass;
}
public void walkThrough(Corridor corridor, Person otherPerson) {
while (wantsToPass) {
// Если сейчас право пройти принадлежит другому человеку,
// немного ждём и снова проверяем ситуацию.
if (corridor.currentPerson != this) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
continue;
}
continue;
}
// Если второй человек тоже хочет пройти,
// вежливо уступаем ему дорогу.
if (otherPerson.wantsToPass()) {
System.out.printf("%s: Проходи первым, %s!%n", name, otherPerson.getName());
corridor.setPerson(otherPerson);
continue;
}
// Если другой человек уже прошёл,
// наконец сами идём по коридору.
corridor.pass();
wantsToPass = false;
System.out.printf("%s: Спасибо, %s!%n", name, otherPerson.getName());
corridor.setPerson(otherPerson);
}
}
}
public static void main(String[] args) { public static void main(String[] args) {
Thread thread1 =
new Thread( final Person ivan = new Person("Иван");
() -> { final Person petr = new Person("Пётр");
while (thread1WantsToPass) {
System.out.println("Поток 1: Я уступаю дорогу Потоку 2..."); // Изначально право пройти по коридору принадлежит Ивану.
ThreadUtils.sleep(100); final Corridor corridor = new Corridor(ivan);
// Первый поток — Иван.
new Thread(
new Runnable() {
public void run() {
ivan.walkThrough(corridor, petr);
} }
})
.start();
System.out.println("Поток 1 прошел!"); // Второй поток — Пётр.
}); new Thread(
new Runnable() {
Thread thread2 = public void run() {
new Thread( petr.walkThrough(corridor, ivan);
() -> {
while (thread2WantsToPass) {
System.out.println("Поток 2: Я уступаю дорогу Потоку 1...");
ThreadUtils.sleep(100);
} }
})
System.out.println("Поток 2 прошел!"); .start();
});
thread1.start();
thread2.start();
} }
} }