java - 为什么静态final变量使用静态方法初始化需要synchronized?

标签 java multithreading thread-safety

在 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()初始化。__parser应该是线程安全的,仅由类加载器加载一次,为什么initParser()需要使用synchronized?是否过量?

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

最佳答案

我认为根本不需要同步。

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

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

(另一方面,这些“安全带和支架”预防措施是无害的,并且对性能的影响微不足道:可能无法衡量。)


郑重声明,类初始化的过程在 JLS Section 12.4.2 中指定。 .

关于java - 为什么静态final变量使用静态方法初始化需要synchronized?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26501549/

相关文章:

java - JFrame 在 ubuntu 上的默认大小

java - java支持编译时多态吗?

c - 我如何让 C 中的多个线程处理二维数组的同一个 for 循环?

java - 基于队列内容的Android多线程作业执行器

c# - 这些静态应用程序属性是否需要锁定?

java - 如何映射 IceFaces <ice :selectInputDate> component on a java. util.Calendar 字段?

c# - C# .NET 中具有多个监听器的线程一次性变量赋值

android - 将消息从服​​务发送到 UI-Thread - 消息在服务处理程序中延迟

java - 在构造函数中设置父子关系而不泄漏 "this"变量

java - java中通过继承访问子类成员与父类实例