我正在阅读 Joshua Bloch 的“Effective Java Second Edition”,我对以下关于并发的声明感到困惑 -
“语言规范保证读取或写入变量是原子的,除非变量的类型为 long 或 double [JLS, 14.4.7]。换句话说,读取除 long 或 double 之外的变量保证返回一个值被某个线程存储到该变量中,即使多个线程同时修改变量并且没有同步。”
如果有人手头有书,这在第 259 页的最后一段中有说明。
即使多个线程正在修改它,引用的变量是否总是有值?
我正在阅读 Joshua Bloch 的“Effective Java Second Edition”,我对以下关于并发的声明感到困惑 -
“语言规范保证读取或写入变量是原子的,除非变量的类型为 long 或 double [JLS, 14.4.7]。换句话说,读取除 long 或 double 之外的变量保证返回一个值被某个线程存储到该变量中,即使多个线程同时修改变量并且没有同步。”
如果有人手头有书,这在第 259 页的最后一段中有说明。
即使多个线程正在修改它,引用的变量是否总是有值?
你必须将句子作为一个整体来阅读。在这里,让我为你改写一下:
“换句话说,读取除 long 或 double 以外的变量,保证返回一个由某个线程存储到该变量中的值,即使多个线程同时修改变量且没有同步”
变成:
“让我们假设变量不是 long 或 double (因为特殊规则适用)。即使有多个线程同时修改变量而没有同步来保护它,那么变量将始终有一个值。
该值将始终是其中一个线程写入的值之一。您将无法提前判断是哪一个,但它始终是其中一个写的值。它永远不会是一个腐败的对半价值。”
volatile如果您有多个线程在未附加关键字的 double 或 long 之间写入和读取。读取可能会获得一个以前从未写入过的值。
这样做的原因是它们是8 字节长而不是 4 字节长,因此您可以读取变量的新值的一半和旧值的另一半(基于特定架构可能不是那么简单,但这就是想法),导致错误的读取从未被写入。
他是说该变量将具有一个值,但该值是不确定的(由于您的并发线程对变量的操作)。