Гарантирует ли замок, что происходит раньше?
У меня вопрос о переупорядочении кода и условиях гонки в Java.
Предположим, у меня есть следующий код с двумя или более потоками, выполняющими одновременно workForThread()
:
public class Job {
private Lock lock = new ReentrantLock();
private int sharedObject = 1;
public void workForThread() {
lock.lock();
try {
sharedObject++;
} finally {
lock.unlock();
}
}
}
Возможно ли, что JVM может выполнить это в неправильном порядке? Например, возможно ли следующее переупорядочение?:
sharedObject++;
lock.lock();
lock.unlock();
Или гарантировано, что блокировка не будет переупорядочена?
Ответы
Ответ 1
Посмотрим, что говорят о Java-интерфейсе в интерфейсе Lock
:
Все реализации блокировки должны обеспечивать такую же синхронизацию памяти семантики, обеспечиваемой встроенной блокировкой монитора, как описано в раздел 17.4 Спецификации языка Java ™:
Успешная операция блокировки имеет одинаковую синхронизацию памяти как успешное действие блокировки.
Успешная операция разблокировки тот же эффект синхронизации памяти, что и успешное действие Unlock.
Итак, ответ на ваш вопрос - да. Lock
дает вам ту же переупорядочивающую гарантию, что обычный блок/метод synchronized
будет.