diff --git a/hw-04/concurrency/src/main/java/com/example/LiveLock.java b/hw-04/concurrency/src/main/java/com/example/LiveLock.java index 678748d..3d6fac9 100644 --- a/hw-04/concurrency/src/main/java/com/example/LiveLock.java +++ b/hw-04/concurrency/src/main/java/com/example/LiveLock.java @@ -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 = - new Thread( - () -> { - while (thread1WantsToPass) { - System.out.println("Поток 1: Я уступаю дорогу Потоку 2..."); - ThreadUtils.sleep(100); + + final Person ivan = new Person("Иван"); + final Person petr = new Person("Пётр"); + + // Изначально право пройти по коридору принадлежит Ивану. + final Corridor corridor = new Corridor(ivan); + + // Первый поток — Иван. + new Thread( + 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 Thread( + new Runnable() { + public void run() { + petr.walkThrough(corridor, ivan); } - - System.out.println("Поток 2 прошел!"); - }); - - thread1.start(); - thread2.start(); + }) + .start(); } }