Гарантирует ли замок, что происходит раньше?

У меня вопрос о переупорядочении кода и условиях гонки в 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 будет.