Java 用于访问volatile实例变量的局部变量
创建对已作为成员字段保留的静态易失性变量的本地引用的目的或价值是什么。这里的代码来自java.util.Scanner JDK 6b14 :“对于所有声明为volatile的变量(包括long和double变量),读取和写入都是原子的。对volatile变量的任何写入都会与该变量的后续读取建立“发生在之前”的关系。” 这意味着读取对模式对象的引用不会中途失败,因为它已更改。volatile关键字应该正好保护这些类型的访问,所以我不认为复制局部变量是为了确保返回有效值 此外,可以在成员字段上执行延迟初始化,而不需要中间局部变量:Java 用于访问volatile实例变量的局部变量,java,oop,design-patterns,volatile,Java,Oop,Design Patterns,Volatile,创建对已作为成员字段保留的静态易失性变量的本地引用的目的或价值是什么。这里的代码来自java.util.Scanner JDK 6b14 :“对于所有声明为volatile的变量(包括long和double变量),读取和写入都是原子的。对volatile变量的任何写入都会与该变量的后续读取建立“发生在之前”的关系。” 这意味着读取对模式对象的引用不会中途失败,因为它已更改。volatile关键字应该正好保护这些类型的访问,所以我不认为复制局部变量是为了确保返回有效值 此外,可以在成员字段上执行延
if (linePattern == null) linePattern = Pattern.compile("...");
它看起来是一个字节码优化,如图所示。使用局部变量会产生更小的字节码(更少的指令)以及更少的对实际值的访问(这是一种昂贵的易失性读取)。但是他们没有同时使用最终的变量优化,所以我对得出这个结论持怀疑态度。,即延迟工作直到真正必要。,即延迟工作直到真正必要。对于
volatile
字段,线型可能在不同的行之间发生变化。将引用复制到局部变量可以确保不会出现不一致的状态。例如,如果你写过
if (linePattern == null)
linePattern = Pattern.compile("...");
然后,linePattern
可能在执行Pattern.compile
时停止为null。对于volatile
字段,linePattern
可能在不同的行之间更改。将引用复制到局部变量可以确保不会出现不一致的状态。例如,如果你写过
if (linePattern == null)
linePattern = Pattern.compile("...");
然后,linePattern
可能在执行Pattern.compile
时停止为空。它保证返回值不为空-即使在检查和返回之间将静态变量设置为空
同时,它是一个不同步的惰性init,需要时可以重新初始化;) 它保证返回值不为NULL-即使静态变量在check和return之间设置为NULL
同时,它是一个不同步的惰性init,需要时可以重新初始化;) 这“加速”了事情的发展。访问volatile
变量的成本很高。Use可以通过将其分配给堆栈变量并访问该变量来避免这种开销,相反,它可以“加速”事情。访问volatile
变量的成本很高。Use可以通过将其分配给堆栈变量并访问该变量来避免这种开销,但是为什么不只是懒洋洋地初始化成员字段呢?该方法正好封装了这一点。它用于获取字段的值,并确保在需要时对其进行初始化。if(linePattern==null)linePattern=new…
这将延迟初始化成员字段,而不是本地变量。但为什么不延迟初始化成员字段呢?该方法正好封装了这一点。它用于获取字段的值,并确保在需要时对其进行初始化。if(linePattern==null)linePattern=new…
这将延迟初始化成员字段,而不是局部变量。volatile关键字保证读取不会重叠,正如我刚才添加的引用中所述。你指的是C语言中的volatile,它用来读取内存映射IO设备吗?不,我指的是Java语言中的volatile。您所陈述的引用意味着<代码> LePaTeTrn < /C>在一个特定的读取或一个特定的写入中间不会重叠,但是如果您正在进行多个读取和/或多个写入,则可以通过这些操作之间的其他线程更改该值。正如我刚才补充的参考文献中所述。你指的是C语言中的volatile,它用来读取内存映射IO设备吗?不,我指的是Java语言中的volatile。您所陈述的引用意味着<代码> LePaTeTrn < /C>在一个特定的读取或一个特定的写入中间不会重叠,但是如果您正在进行多个读取和/或多个写入,则可以通过这些操作之间的其他线程来改变该值。