Wait-notify relock. Обеспечит ли happens-before между потоками?

236
08 мая 2018, 01:35

Как известно, освобождение монитора и последующий захват этого же монитора другим потоком соотносятся как happens-before, т.е. T1[unlock:monitor1]<<T2[lock:monitor1].

Вопрос:
Допустим, что поток T2 сейчас ожидает в wait() по некоторому монитору, а поток T1 вызвал синхронизированный по этому монитору метод, из которого вызвал notifyAll() и отпустил монитор. Будет ли считаться, что отпускание монитора потоком T1 (т.е. просто выход из метода) happens-before поток T2 вышел из wait() снова забрав блокировку.

Очень прошу, ответьте на мой вопрос. Он каверзный и мне не хватает сил найти источники, где достоверно точно сказано, что выход из wait() включает в себя полноценный захват блокировки, и что happens-before правило для междупоточных relock'ов здесь будет сохраняться.

ВНИМАНИЕ: оставшаяся часть вопроса требует вникания. Вы можете дать ответ не читая остальное. Вопрос самодостаточно сформулирован и без примеров кода.

Иллюстрация вопроса:

package attempt;
import java.util.concurrent.*;
class Writer implements Runnable {
    public void run() {
        Main.x = 1;
        Main.methodWait();     // (1)
    }
}
class Reader implements Runnable {
    public void run() {
        Main.methodNotify();   // (2)
        System.out.println(Main.x);
    }
}
public class Main {
    public static int x = 0;
    public static boolean flag = false;
    public static synchronized void methodWait() {
        try {
            while (!flag)
                Main.class.wait();
        } catch (InterruptedException e) {
            System.err.println("Impossible");
        }
    }
    public static synchronized void methodNotify() {
        flag = true;
        Main.class.notifyAll();
    }
    public static void main(String[] args) throws Exception{
        ExecutorService exec = Executors.newCachedThreadPool();
        exec.execute(new Writer());
        Thread.sleep(500);
        exec.execute(new Reader());
        exec.shutdown();
    }
}

Для этого кода вопрос звучит так:
Правда ли, что строки (1) и (2) полностью обеспечивают собой happens-before? Если правда, то почему?

(Считаем, что sleep() в main() обеспечил, что writer физически раньше выполнился до ожидания в methodWait() чем reader вообще запустился в потоке)

READ ALSO
Проблема с рефлексией в .jar файле

Проблема с рефлексией в .jar файле

у меня следующая проблема: созданный проект и intellij находит все классы в проекте посредством рефлексии, но при собирании проекта вjar файл рефлексия...

213
Извлечение autogererated-ключа используя PreparedStatement или JdbcTemplate

Извлечение autogererated-ключа используя PreparedStatement или JdbcTemplate

Пожалуйста, объясните как можно используя каждый из этих способов извлекать ключК пример есть:

208
залить фигуру картинкой java

залить фигуру картинкой java

Задача учебная на javaВ ней есть объект, который выглядит как круг и двигается за целью (типа игра)

197
Как через уведомление вызвать метод из службы в другом активити

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

Как через кнопку в уведомлении вызвать метод processIntent() в MainActivityВ уведомлении я прописал кнопки

227