chore: organize homework into first-part directory
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
package com.example;
|
||||
|
||||
import com.example.util.ThreadUtils;
|
||||
|
||||
public class DeadLock {
|
||||
|
||||
private static final Object LOCK_A = new Object();
|
||||
private static final Object LOCK_B = new Object();
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
Thread thread1 =
|
||||
new Thread(
|
||||
() -> {
|
||||
synchronized (LOCK_A) {
|
||||
System.out.println("Thread 1: получил LOCK_A");
|
||||
|
||||
ThreadUtils.sleep(100);
|
||||
|
||||
System.out.println("Thread 1: пытается получить LOCK_B");
|
||||
|
||||
synchronized (LOCK_B) {
|
||||
System.out.println("Thread 1: получил LOCK_B");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Thread thread2 =
|
||||
new Thread(
|
||||
() -> {
|
||||
synchronized (LOCK_B) {
|
||||
System.out.println("Thread 2: получил LOCK_B");
|
||||
|
||||
ThreadUtils.sleep(100);
|
||||
|
||||
System.out.println("Thread 2: пытается получить LOCK_A");
|
||||
|
||||
synchronized (LOCK_A) {
|
||||
System.out.println("Thread 2: получил LOCK_A");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
thread1.start();
|
||||
thread2.start();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.example;
|
||||
|
||||
public class LiveLock {
|
||||
|
||||
static class Corridor {
|
||||
private Person currentPerson;
|
||||
|
||||
public Corridor(Person person) {
|
||||
currentPerson = person;
|
||||
}
|
||||
|
||||
public synchronized void setPerson(Person person) {
|
||||
currentPerson = person;
|
||||
}
|
||||
|
||||
public synchronized Person getPerson() {
|
||||
return currentPerson;
|
||||
}
|
||||
|
||||
public synchronized void pass() {
|
||||
System.out.printf("%s прошёл по коридору!%n", currentPerson.name);
|
||||
}
|
||||
}
|
||||
|
||||
static class Person {
|
||||
private final String name;
|
||||
private volatile 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.getPerson() != this) {
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
return;
|
||||
}
|
||||
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) {
|
||||
|
||||
final Person ivan = new Person("Иван");
|
||||
final Person petr = new Person("Пётр");
|
||||
|
||||
// Изначально право пройти по коридору принадлежит Ивану.
|
||||
final Corridor corridor = new Corridor(ivan);
|
||||
|
||||
// Первый поток — Иван.
|
||||
new Thread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ivan.walkThrough(corridor, petr);
|
||||
}
|
||||
})
|
||||
.start();
|
||||
|
||||
// Второй поток — Пётр.
|
||||
new Thread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
petr.walkThrough(corridor, ivan);
|
||||
}
|
||||
})
|
||||
.start();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.example.util;
|
||||
|
||||
public class ThreadUtils {
|
||||
|
||||
public static void sleep(long millis) {
|
||||
try {
|
||||
Thread.sleep(millis);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.example;
|
||||
|
||||
public class TwoThreads {
|
||||
|
||||
private static final Object lock = new Object();
|
||||
private static boolean turnOne = true;
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
Thread thread1 =
|
||||
new Thread(
|
||||
() -> {
|
||||
while (true) {
|
||||
synchronized (lock) {
|
||||
while (!turnOne) {
|
||||
try {
|
||||
lock.wait();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
System.out.print("1");
|
||||
turnOne = false;
|
||||
lock.notifyAll();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Thread thread2 =
|
||||
new Thread(
|
||||
() -> {
|
||||
while (true) {
|
||||
synchronized (lock) {
|
||||
while (turnOne) {
|
||||
try {
|
||||
lock.wait();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
System.out.print("2");
|
||||
turnOne = true;
|
||||
lock.notifyAll();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
thread1.start();
|
||||
thread2.start();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user