为什么静态最终变量使用静态方法初始化需要同步?

ykgarfield

在Jetty源代码中,该jetty-xml模块XmlConfiguration具有以下代码:

java private static final XmlParser __parser = initParser();

private synchronized static XmlParser initParser() {
XmlParser parser = new XmlParser();
URL config60 = Loader.getResource(XmlConfiguration.class, "org/eclipse/jetty/xml/configure_6_0.dtd");
URL config76 = Loader.getResource(XmlConfiguration.class, "org/eclipse/jetty/xml/configure_7_6.dtd");
URL config90 = Loader.getResource(XmlConfiguration.class, "org/eclipse/jetty/xml/configure_9_0.dtd");

parser.redirectEntity("configure.dtd", config90);
parser.redirectEntity("configure_1_0.dtd", config60);
parser.redirectEntity("configure_1_1.dtd", config60);

...

return parser;

__parser变量使用静态方法initParser()initialization.the__parser应该是线程安全的,只有一次由类加载器,为什么加载initParser()需要使用synchronized是否过量?

进一步说明:我从jetty-start模块调试Jetty源代码,然后调用该jetty-xml模块。

斯蒂芬·C

我认为它根本不需要同步。

Java语言规范保证Java类初始化(即类statics的初始化,等等)在一个锁内执行,以防止出现竞争情况。无论是一次加载类还是多次加载该类(即通过不同的类加载器),这都适用。

我怀疑这段代码的作者根本不知道JVM如何处理此问题,并且正在采取不必要的预防措施。

(另一方面,这些“安全带”预防措施是无害的,并且对性能的影响很小:可能无法衡量。)


作为记录,类的初始化过程在JLS的12.4.2节中指定

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么在静态初始化块中不允许使用合格的静态最终变量?

什么时候应该使用未初始化的静态最终变量?

静态最终变量和静态初始化程序块

为什么非常数静态变量需要在类外部初始化?

如果引用的静态字段是最终的,为什么不执行静态初始化程序

在Java中,不使用静态变量或类变量的方法是否需要同步?

为什么Java不允许在构造函数中初始化静态最终变量(例如static final int d)?

从静态块或方法初始化静态最终int并在批注中使用它

为什么在这里允许使用非const初始化静态变量?

如何初始化基于CMD ARGS静态最终变量?

无法在try / catch中初始化静态最终变量

类加载与初始化:Java静态最终变量

在Java的子类(子类)中初始化静态最终变量

为什么超类中的静态块/静态变量在main之前初始化?

为什么在初始化私有静态成员时允许调用私有静态方法?

Java-最终变量可以在静态初始化块中初始化吗?

Java如何初始化静态变量和静态方法?(使用简单代码)

使用任何静态方法之前,请确保静态变量已初始化?

为什么最终实例变量不需要初始化,而最终局部变量不需要初始化?

构造函数是否需要初始化静态变量?

为什么不能用其他变量的值初始化静态变量?

为什么一个静态变量的一个方法调用返回另一个静态变量保持为空初始化?

为什么需要静态char *而不是static char **进行常量初始化

非最终静态字段的静态初始化安全吗?

春季:当Java中有静态和非静态初始化程序时,为什么需要InitializingBean的afterPropertiesSet()?

行为差异:“ null”初始化的最终静态成员和“ null”初始化的最终局部变量

为什么要在声明静态变量之前对其进行初始化

为什么const指针差异不能用作静态变量的初始化程序?

为什么未初始化模板类的嵌入式静态变量?