通过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实现LockLock的文档包括:

所有Lock实现必须强制执行内置监视器锁提供的相同内存同步语义,如Java语言规范,第三版(17.4内存模型)中所述:

  • 成功的lock操作具有与成功lock操作相同的内存同步效果。
  • 成功unlock操作具有与成功unlock操作相同的内存同步效果。