2009-10-15 123 views
23

我的问题涉及ReentrantLock的使用是否保证字段的可见性与synchronized关键字提供的方面相同。通过ReentrantLock访问字段是否需要volatile关键字?

例如,在下面的类,场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(); 
    } 
    } 
} 

我知道无论如何使用volatile关键字只会影响性能,但我仍然希望能够正确编写代码。

回答

28

它没有波动是安全的。 ReentrantLock实现Lock,并且docs for Lock包括这样的:

所有Lock实现必须执行 同一存储器的同步通过提供 语义内置 监视器锁定,以Java 语言规范,第3版 (17.4内存模型):

  • 成功lock操作具有相同 内存同步效果 成功Lock操作。
  • 成功 unlock操作具有相同内存 同步效果为 成功Unlock操作。
+0

这个建议是否适用于由于现场吊装而引起的“场(场)”? – Pod 2017-08-21 09:49:16

+0

@Pod:没有关于'while'循环如何与锁相互作用的更多具体细节,这是不可能的。你可能想用一个具体的例子来创建一个新的问题。 – 2017-08-21 09:50:35