在getter上是volatile还是在setter上同步,两者同步?

时间:2015-04-04 11:04:52

标签: java concurrency synchronized volatile

在并发程序中,这是安全的吗?


private volatile int i;

public int getI() {
    return i;
}

public synchronized incrementI() {
    i++;
}

据我所知synchronize,只有在同一对象上获取锁定监视器的线程才能保证i上的更改可用。 所以我认为,上面的代码并不安全。如果是真的请确认,否则请解释。 感谢。

3 个答案:

答案 0 :(得分:1)

此代码是线程安全的。 synchronized方法中的更改将传递给所有线程。 因为你已经使它变得易变,所有线程都不会缓存它,所以会得到最新的副本。

此线程也很有用Java volatile modifier and synchronized blocks

答案 1 :(得分:1)

几乎所有的例子都在" JMM Pragmatics" here

假设getter实际观察到设定值,

volatile提供事先发生的边缘,以便在setter对getter之后发生的所有事情可见之前进行更改。 setter 中的synchronized另外给出了相互排斥,volatile不能单独保证。

答案 2 :(得分:0)

由于Integer i是类的私有实例变量,因此synchronize实例方法将起作用。您需要确保添加到修改i的类的所有方法必须使用相同的对象监视器进行同步。

请注意i ++不是自动表达式,因此只有volatile不起作用。

您可以像这样使用AtomicInteger作为单个值。