波动与同步在一起

时间:2012-04-12 11:46:04

标签: java multithreading

有没有理由在此代码中使用volatile和synchronized?

public class Helper {
  private volatile int n;
  private final Object lock = new Object();
  public Helper(int n) {
    this.n = n;
  }

  public void setN(int value) {
    synchronized (lock) {
      n = value;
    }
  }
}

Class Helper必须是线程安全的。我从“Java并发指南”一书中得到了这个例子,但是仍然不清楚:在这个例子中使用volatile和synchronized的原因是什么?

3 个答案:

答案 0 :(得分:7)

此示例的目的是指出在这种情况下syncronized volatile是不够的,因为对象可以不安全地发布(即volatile中没有Foo {1}}):

  

如果Foo类中的辅助字段未声明为volatile,则应将n字段声明为volatile,以便在初始化n和将Helper写入辅助字段之间建立before-before关系。这符合指南“VNA06-J。不要认为声明对象引用volatile会保证第35页的成员可见性。仅当调用者(类Foo)无法信任声明助手volatile时才需要这样做。

这是正确的,但他们选择了一个不好的例子来证明它,因为volatile没有同步化就足够了。

答案 1 :(得分:1)

没有必要将同步块放在值的变化周围;从Java 5开始,这对于volatile变量“自动”完成。我认为在Java 5之前,情况不一定如此。

答案 2 :(得分:0)

我猜使用volatile是因为'n'在构造函数中设置了