Я бы использовал переменную условия volatile
, но я думаю, что volatile
является избыточным. Кроме того, я не совсем уверен, что я понял эту точку из https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/package-summary.html#MemoryVisibility правильно:Охраняемые блоки в Java. Где я должен обновить переменную условия?
анлок (синхронизированный блок или выход метода) монитора происходит, перед каждым последующей блокировкой (синхронизированный блок или метод входа) в том, что такой же монитор. И поскольку отношение «дожидается» до транзитивно, все действия потока перед разблокировкой происходят до всех действий, следующих за любой блокировкой потока, которая находится на мониторе .
So synchronized
блоки называются впоследствии. Но являются ли результаты присвоений, выполненных в блоке synchronized
, видимым для всех последующих блоков synchronized
?
Образец приложения.
package sample;
public class Foo {
private boolean shouldWait;
private final Object lock = new Object();
void blockThread() {
synchronized (lock) {
shouldWait = true;
while (shouldWait) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
void notifyThread() {
synchronized (lock) {
shouldWait = false;
lock.notify();
}
}
}
Тест.
package sample;
public class Main {
private static Foo foo = new Foo();
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
foo.blockThread();
}
}).start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
new Thread(new Runnable() {
@Override
public void run() {
foo.notifyThread();
}
}).start();
}
}
Спасибо. Но есть ли у вас ссылка на официальную документацию, которая может подтвердить ваш ответ? –
* Запись в нестабильное поле происходит до каждого последующего чтения этого же поля. Записи и чтения волатильных полей имеют аналогичные эффекты согласованности с памятью как входные и выходящие мониторы, но не влекут за собой блокировку взаимного исключения. * Это из вашей ссылки. –