Подтвердить что ты не робот

Требуется ли ключевое слово volatile для полей, доступных через ReentrantLock?

Мой вопрос относится к тому, что использование ReentrantLock гарантирует видимость поля в том же отношении, что и синхронизированное ключевое слово.

Например, в следующем классе A поле sharedData не обязательно должно быть объявлено volatile при использовании ключевого слова synchronized.

class A 
{
  private double sharedData;

  public synchronized void method() 
  {
    double temp = sharedData;
    temp *= 2.5;
    sharedData = temp + 1;
  } 
}

В следующем примере, используя ReentrantLock, нужно ли ключевое слово volatile в нужном поле?

class B 
{
  private final ReentrantLock lock = new ReentrantLock();
  private volatile double sharedData;

  public void method() 
  {
    lock.lock();
    try
    {
      double temp = sharedData;
      temp *= 2.5;
      sharedData = temp + 1;
    }
    finally
    {
      lock.unlock();
    }
  } 
}

Я знаю, что использование ключевого слова volatile в любом случае, скорее всего, приведет к незначительному результату производительности, но я все равно хотел бы правильно кодировать.

4b9b3361

Ответ 1

Это безопасно без волатильности. ReentrantLock реализует Lock, а docs для Lock включает в себя следующее:

Все реализации Lock должны обеспечивать соблюдение такая же синхронизация памяти семантика, предоставляемая встроенным блокировка монитора, как описано в разделе "Java" Спецификация языка, третье издание (17.4 Модель памяти):

  • Успешная операция Lock имеет такие же эффекты синхронизации памяти, как и успешное действие Lock.
  • Успешный Операция unlock имеет одинаковую память эффекты синхронизации как успешное действие unlock.