通过重入锁访问的字段是否需要 volatile 关键字?

我的问题是,使用 ReentrantLock 是否能保证字段的可见性与同步关键字提供的相同方面。

例如,在下面的类 A 中,在使用同步关键字时,不需要将字段 sharedData 声明为易失性。

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();
    }
  } 
}

我知道无论如何使用volfine关键字只会带来微不足道的性能损失,但我仍然希望正确编码。


答案 1

它是安全的,没有波动。 实现 ,而 Lock 的文档包括:ReentrantLockLock

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

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

答案 2

推荐