Синхронизация в Java

182
19 ноября 2017, 13:45
@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, очень жду помощи что именно происходит в таком варианте событий.

Answer 1

Когда вы делаете 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();
        }
    }
}
READ ALSO
Веб-приложение на Java

Веб-приложение на Java

Нужно реализовать MVC приложение на JavaБудет одна общая БД для веб-приложения и для Android-приложение

208
Сделать код элегантным

Сделать код элегантным

Надо сделать заглавными последние буквы каждого словаНо CodeHunt не считает мой код самым коротким

131
Поиск по SQLite через EditText

Поиск по SQLite через EditText

Вопрос наверное слишком общий, но на конкретном примере моего кода может подскажите ктоУ меня есть DialogFragment:

142
Windows api documentation

Windows api documentation

Где можно найти документацию для создания приложений на java под винду? Пересмотрел много источниковНо не нашел ничего толкового

154