Java 中的易失性 int 是线程安全的吗?

Java 中的易失性是线程安全的吗?也就是说,是否可以在不锁定的情况下安全地读取和写入它?int


答案 1

是的,你可以从中读取并安全地写入它 - 但你不能做任何复合,比如安全地增加它,因为这是一个读/修改/写周期。还有一个问题是它如何与其他变量的访问进行交互。

坦率地说,易失性的确切性质令人困惑(有关更多详细信息,请参阅JLS的内存模型部分) - 我个人通常会使用AtomicInteger代替,作为确保我正确理解的更简单的方法。


答案 2

[...]就像能够在不锁定的情况下安全地读取和写入一样?

是的,读取将始终产生上次写入的值(读取和写入都是原子操作)。

易失性读/写在执行中引入了所谓的“发生前”关系。

摘自 Java 语言规范 第 17 章:线程和锁

对易失性字段 (§8.3.1.4) 的写入发生在每次后续读取该字段之前。

换句话说,在处理可变变量时,您不必使用关键字显式同步(引入发生前关系),以确保线程获得写入变量的最新值。synchronized

正如 Jon Skeet 所指出的,可变变量的使用是有限的,你通常应该考虑使用包中的类。java.util.concurrent