Java 公共静态final int线程安全吗?

Java 公共静态final int线程安全吗?,java,thread-safety,Java,Thread Safety,我希望有一个从多个线程访问常数的文件。对于这个问题,让一个类具有大量的公共静态final ints是安全的实现吗?是的,它是安全的 该值永远不会改变,因此不存在比赛条件的风险。Java保证在任何东西尝试使用该值之前对其进行初始化 出于其他原因(设计的清晰性等),它是否是最好的架构是另一个问题。是的,100%安全。这是最终决定,所以没有人能改变它。每个线程都必须以只读方式访问,并且不存在只读的争用。对于原语,使它们成为最终的使它们成为编译时常量(如果直接初始化,而不是作为方法的结果),而int是原

我希望有一个从多个线程访问常数的文件。对于这个问题,让一个类具有大量的
公共静态final int
s是安全的实现吗?

是的,它是安全的

该值永远不会改变,因此不存在比赛条件的风险。Java保证在任何东西尝试使用该值之前对其进行初始化


出于其他原因(设计的清晰性等),它是否是最好的架构是另一个问题。

是的,100%安全。这是最终决定,所以没有人能改变它。每个线程都必须以只读方式访问,并且不存在只读的争用。

对于原语,使它们成为
最终的
使它们成为编译时常量(如果直接初始化,而不是作为方法的结果),而
int
是原语。因此,
final int
使其不可变,因此是线程安全的。

是的,它是线程安全的。任何
静态final
变量都保证在类初始化后初始化。因此,一旦包含这样一个
静态final
变量的类在代码中的任何地方被使用,它总是被完全初始化(即值被设置)

使用原语
int
,这种情况更加严重。原语
静态final
变量(与
字符串
相同)是一个所谓的变量,由Java编译器javac内联。唯一的要求是该值可以由Java编译器计算,即它不能是非常量计算的结果。当您编写要定义常量的代码时,我假设这不适用于您的用例。因此,这些常量值被直接复制到它们的访问位置,从而减少了
静态final
变量通过反射进行更改的非线程安全性,这假设是非原语类型的问题


此外,使用这些变量是一个好主意,因为它避免了使用所谓的。

一般来说(除非您刻意使其不真实),类在您可以引用其中的任何内容之前已完全初始化,因此静态初始化将从其他线程可见,无需任何显式同步。
final
变量可以通过反射(或代码生成,因为JVM不强制执行
final
变量。)
静态final
不会自动使字段编译时间恒定。这取决于我们初始化它的方式(如果它是从文件中读取数据的方法的结果,那么它的值将在运行时设置,这意味着编译器无法知道它)。“对于原语,使它们成为
final
使它们成为编译时常量”您几乎做到了,但这还不是故事的结尾。要在正确的声明旁边创建编译时常量,还需要正确的初始化。在这种情况下,值必须直接输入,它不能是某个方法的结果,例如从文件中读取它(这必须在运行时发生,这意味着编译器将无法了解它)。“而不是作为方法/表达式结果”表达式如果基于其他编译时常量,则可以使用。编译器将
1+2+3
更改为
6
“foo”+“bar”
将编译为
“foobar”
@Pshemo-但字符串a=“a”;字符串b=“b”;只有当a和b都是最终值时,才会在编译时确定字符串s=a+b。我在考虑这个例子,我没有说所有的表达式都可以,只是那些基于编译时常量的表达式。