getter 上的 volatile 和 setter 上的同步是否与两者上的同步相同?
Is volatile on getter and synchronized on setter the same as synchronized on both?
在并发程序中,这样安全吗:
private volatile int i;
public int getI() {
return i;
}
public synchronized incrementI() {
i++;
}
?
根据我对 synchronize
的了解,更改保证在 i
上仅适用于在同一对象上获取锁监视器的线程。
所以我认为,上面的代码是不安全的。如果为真请确认,否则请说明。
谢谢。
这段代码是线程安全的。同步方法中的更改会传递给所有线程。
由于您已将其设为易失性,因此所有线程都不会缓存它,因此将获取最新副本。
这个帖子也会有帮助Java volatile modifier and synchronized blocks
由于 Integer i 是 class 的私有实例变量,同步实例方法将起作用。您需要确保添加到 class 的所有修改 i 的方法都必须使用相同的对象监视器进行同步。
请注意 i++ 不是自动表达式,因此只有 volatile 不起作用。
您可以像这样将 AtomicInteger 用于单个值。
几乎在"JMM Pragmatics"here中给出了确切的例子。
volatile
提供 happens-before 边缘,使 setter 之前的更改对 getter 之后发生的所有事情可见,假设 getter 实际观察到设定值。 synchronized
在setter中另外给出互斥,即volatile
单独不保证。
在并发程序中,这样安全吗:
private volatile int i;
public int getI() {
return i;
}
public synchronized incrementI() {
i++;
}
?
根据我对 synchronize
的了解,更改保证在 i
上仅适用于在同一对象上获取锁监视器的线程。
所以我认为,上面的代码是不安全的。如果为真请确认,否则请说明。
谢谢。
这段代码是线程安全的。同步方法中的更改会传递给所有线程。 由于您已将其设为易失性,因此所有线程都不会缓存它,因此将获取最新副本。
这个帖子也会有帮助Java volatile modifier and synchronized blocks
由于 Integer i 是 class 的私有实例变量,同步实例方法将起作用。您需要确保添加到 class 的所有修改 i 的方法都必须使用相同的对象监视器进行同步。
请注意 i++ 不是自动表达式,因此只有 volatile 不起作用。
您可以像这样将 AtomicInteger 用于单个值。
几乎在"JMM Pragmatics"here中给出了确切的例子。
volatile
提供 happens-before 边缘,使 setter 之前的更改对 getter 之后发生的所有事情可见,假设 getter 实际观察到设定值。 synchronized
在setter中另外给出互斥,即volatile
单独不保证。