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;
import com.example.util.ThreadUtils;
public class LiveLock {
private static boolean thread1WantsToPass = true;
private static boolean thread2WantsToPass = true;
static class Corridor {
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) {
Thread thread1 =
final Person ivan = new Person("Иван");
final Person petr = new Person("Пётр");
// Изначально право пройти по коридору принадлежит Ивану.
final Corridor corridor = new Corridor(ivan);
// Первый поток — Иван.
new Thread(
() -> {
while (thread1WantsToPass) {
System.out.println("Поток 1: Я уступаю дорогу Потоку 2...");
ThreadUtils.sleep(100);
new Runnable() {
public void run() {
ivan.walkThrough(corridor, petr);
}
})
.start();
System.out.println("Поток 1 прошел!");
});
Thread thread2 =
// Второй поток — Пётр.
new Thread(
() -> {
while (thread2WantsToPass) {
System.out.println("Поток 2: Я уступаю дорогу Потоку 1...");
ThreadUtils.sleep(100);
new Runnable() {
public void run() {
petr.walkThrough(corridor, ivan);
}
System.out.println("Поток 2 прошел!");
});
thread1.start();
thread2.start();
})
.start();
}
}