@ThreadSafe
public class MyLock {
@GuardedBy("lock")
volatile Boolean lock = false;
public MyLock() {
}
public void lock() throws InterruptedException {
if (lock) {
synchronized (lock) {
System.out.println(Thread.currentThread().getName());
lock.wait();
}
} else {
lock = true;
}
}
public void unlock() {
lock = false;
synchronized (lock) {
lock.notify();
}
}
} `
Смысл такой: заходят три потока с очередностью в три секунды, первый поток как надо проходит остальные два ждут, но когда доходит до просыпания потоки не просыпаются в debug так и остаются в состоянии waiting.
Исправить знаю как, нашел один способ либо весь метод сделать synchronized или все тело внутри метода в synchronized block завести, но по сути этот вариант тоже должен рабочий ведь переменная volatile, очень жду помощи что именно происходит в таком варианте событий.
Когда вы делаете lock = false; у вас меняется объект в lock, и вы вызываете notifyAll() не на том объекте, на котором делаете wait().
Сделайте мьютекс отдельно, флаг отдельно и меняйте флаг после захвата мьютекса. Ожидание так же нужно делать в цикле, т.к. проснувшийся поток может снова войти в критическую секцию уже после того, как флаг снова изменится.
@ThreadSafe
public class MyLock {
final Object mutex = new Object();
@GuardedBy("mutex")
boolean locked = false;
public MyLock() {
}
public void lock() throws InterruptedException {
synchronized (mutex) {
while (locked) {
System.out.println(Thread.currentThread().getName());
mutex.wait();
}
locked = true;
}
}
public void unlock() {
synchronized (mutex) {
locked = false;
mutex.notify();
}
}
}
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости