我的问题是关于ReentrantLock的使用是否可以保证字段的可见性(与synced关键字提供的方面相同)。
例如,在以下类 A中 ,由于使用了 synced关键字 ,因此无需将 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关键字都只会对性能造成微不足道的影响,但我仍然想正确编码。
没有波动是安全的。ReentrantLock实现Lock,文档Lock包括:
ReentrantLock
Lock
所有Lock实现必须强制执行与内置监视器锁所提供的相同的内存同步语义,如Java语言规范第三版(17.4内存模型)中所述: 成功的lock操作与成功的操作具有相同的内存同步效果Lock。 成功的unlock操作与成功的 操作具有相同的内存同步效果Unlock。
所有Lock实现必须强制执行与内置监视器锁所提供的相同的内存同步语义,如Java语言规范第三版(17.4内存模型)中所述:
lock
unlock
Unlock