通过ReentrantLock访问的字段是否需要volatile关键字?
我的问题是指使用ReentrantLock是否保证字段的可见性与synchronized关键字提供的方面相同。
例如,在下面的类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关键字只会造成微不足道的性能损失,但我仍然希望正确编码。
没有波动性,它是安全的。 ReentrantLock
实现Lock
, Lock
的文档包括:
所有
Lock
实现必须强制执行内置监视器锁提供的相同内存同步语义,如Java语言规范,第三版(17.4内存模型)中所述:
- 成功的
lock
操作具有与成功lock
操作相同的内存同步效果。- 成功
unlock
操作具有与成功unlock
操作相同的内存同步效果。