Требуется ли ключевое слово volatile для полей, доступных через ReentrantLock?
Мой вопрос касается того, гарантирует ли использование ReentrantLock видимость поля в том же отношении, что и ключевое слово synchronized.
Например, в следующем классе A поле sharedData не нужно объявлять volatile, поскольку используется синхронизированное ключевое слово.
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, скорее всего, приведет к минимальному снижению производительности, но я все равно хотел бы правильно написать код.
1 ответ
Это безопасно без волатильности. ReentrantLock
инвентарь Lock
и документы дляLock
включите это:
Все
Lock
Реализации должны применять ту же семантику синхронизации памяти, которая предусмотрена встроенной блокировкой монитора, как описано в Спецификации языка Java, третье издание (17.4 Модель памяти):
- Успешный
lock
операция имеет те же эффекты синхронизации памяти, что и успешнаяLock
действие.- Успешный
unlock
операция имеет те же эффекты синхронизации памяти, что и успешнаяUnlock
действие.