一尘不染

通过ReentrantLock访问的字段是否需要volatile关键字?

java

我的问题是关于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关键字都只会对性能造成微不足道的影响,但我仍然想正确编码。


阅读 404

收藏
2020-12-03

共1个答案

一尘不染

没有波动是安全的。ReentrantLock实现Lock文档Lock包括:

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

  • 成功的lock操作与成功的操作具有相同的内存同步效果Lock
  • 成功的unlock操作与成功的 操作具有相同的内存同步效果Unlock
2020-12-03