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

标签 java concurrency locking volatile reentrancy

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

例如,在下面的类A中,字段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 实现 Lockdocs for Lock包括这个:

All Lock implementations must enforce the same memory synchronization semantics as provided by the built-in monitor lock, as described in The Java Language Specification, Third Edition (17.4 Memory Model):

  • A successful lock operation has the same memory synchronization effects as a successful Lock action.
  • A successful unlock operation has the same memory synchronization effects as a successful Unlock action.

关于java - 通过 ReentrantLock 访问的字段是否需要 volatile 关键字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1570589/

相关文章:

java - Hibernate:插入回具有相同ID的已删除行

java - GWT:从 HTML 中查找 Java 源代码

sockets - 在 goroutines 中使用套接字的正确方法是什么

locking - 我们对事务内存的要求是否过高?

java - ListView 打开相同的 Activity

java - 在 iReports 中调整 JFreeChart

concurrency - Clojure 中的死简单 Fork-Join 并发

Java并发任务实现

Java锁定条件等待并通知: IllegalMonitorStateException

c++ - boost::lock 在 boost 1.53 中无法编译