同步访问需要Java volatile吗?

时间:2015-12-07 21:50:36

标签: java concurrency synchronized volatile

在以下情况中,volatile是多余的?删除volatile会有什么不同吗?或者,离开volatile但是删除synchronized块和synchronized修饰符会有什么不同吗?

private volatile boolean registered;

synchronized boolean registered() {
  return registered;
}

void setRegistered(boolean registered) {
  synchronized (this) {
    this.registered = registered;
  }
}

1 个答案:

答案 0 :(得分:2)

不,除非您有其他未显示的访问权限,否则registered没有volatile即可。

我认为,删除volatile会稍微加快代码速度。但我认为删除volatile的主要好处是它可以清理维护者的代码。

在这种情况下,volatile和我可以看到的同步方法没有区别,所以请使用其中一个。 (除非同步方法使您使用的对象保护registered字段 public ,这可能是好的和坏的。私有volatile使同步锁保持私有。 )

如果您有这样的课程,请尝试澄清最后一条陈述:

public class Reg {
    private boolean registered;

    synchronized boolean registered() {
      return registered;
    }

    void setRegistered(boolean registered) {
      synchronized (this) {
        this.registered = registered;
      }
    }
}

然后您创建一个新实例:

public class Test {
  public static Reg reg;
  public void static main( String... args ) {
     reg = new Reg();
     synchronized( reg ) {
            // do stuff
     }
  }
}

reg.registered()中的锁定被占用时,其他任何试图访问Test的人都会阻止,直到锁定被释放为止。该锁是公开给任何可以看到该对象的人。这可能是好事也可能是坏事。它允许其他类控制对您的方法的访问,这可能对原子性有好处,但它也可能将一些线程控制烘焙到源库中,在那里它被遍布,而不是仅由一个类封装。好和坏。可能还有其他一些例子,说明为什么这可能是好的和坏的,这只是一个。