int字段的读取应该同步吗?



在《Java并发性实践》一书中附加了以下代码:

public class Counter {
private long value = 0;
public synchronized long getValue() {
return value;
}
public synchronized void increment() {
++value;
}
}

这里是long类型的value字段,以及同步的读和增量方法。

我是否正确理解了read方法的同步只需要用于long和double类型,因为它们不是原子类型?如果字段值是int类型,那么read方法的同步将是不必要的?

需要同步getValue方法

在Java中,synchronized关键字为您提供了可见性和原子性保证。根据经验,您应该记住编译器开发人员和CPU供应商可以自由地进行优化,例如内存重新排序或将寄存器中的变量缓存为,只要优化后的程序在单线程环境中保持不变。

现在让我们看看当不同的线程调用getValueincrement方法时,getValue不再同步时会发生什么。从JVM的角度来看,任何只读取value而从不通过increment方法更新它的线程实际上总是读取相同的常量值。因此,在读取线程中,JVM可能会选择将变量保存在寄存器中,而不再从内存中读取它!

正如注释所建议的,可以通过将value的类型从int更改为AtomicInteger来删除synchronized关键字。但是,即使您不想使用AtomicInteger,您也可以这样重写您的类:

public class Counter {
private volatile int value = 0;
public int getValue() {
return value;
}
public synchronized void increment() {
++value;
}
}

volatile关键字将确保可见性,并且读取不再需要任何锁定。我建议检查这些参考资料以了解更多关于Java内存模型的信息:

https://jenkov.com/tutorials/java-concurrency/index.html

https://docs.oracle.com/javase/specs/jls/se17/html/jls - 17. - html

最新更新