java - 类初始化和同步类方法

标签 java multithreading concurrency synchronization

在我的应用程序中,有一个类如下:

public class Client {
    public synchronized static print() {
        System.out.println("hello");
    }

    static {
        doSomething(); // which will take some time to complete
    }
}

该类将用于多线程环境,多个线程可能同时调用Client.print()方法。请问有没有可能是thread-1触发类初始化,在类初始化完成前,thread-2进入print方法,打印出“hello”字符串?

我在生产系统(64 位 JVM + Windows 2008R2)中看到了这种行为,但是,我无法在任何环境中使用简单的程序重现这种行为。

在 Java 语言规范的第 12.4.1 节 (http://java.sun.com/docs/books/jls/second_edition/html/execution.doc.html) 中,它说:

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

  • T is a class and an instance of T is created.
  • T is a class and a static method declared by T is invoked.
  • A static field declared by T is assigned.
  • A static field declared by T is used and the reference to the field is not a compile-time constant (§15.28). References to compile-time constants must be resolved at compile time to a copy of the compile-time constant value, so uses of such a field never cause initialization.

根据这段,类初始化将在调用静态方法之前进行,但是,尚不清楚类初始化是否需要在调用静态方法之前完成 .根据我的直觉,JVM 应该在进入其静态方法之前强制完成类初始化,并且我的一些实验支持我的猜测。但是,我确实在另一个环境中看到了相反的行为。有人可以告诉我一些关于这个的信息吗?

感谢任何帮助,谢谢。

最佳答案

我对引用文本的理解是类初始化过程在调用 T 声明的静态方法之前完成(初始化) em>.

will be initialized 表示初始化过程已经开始,已经终止。

因此(根据我的理解)应该不可能,因为线程 A 调用了 print 而执行了静态初始化程序,而另一个线程已经可以调用 print

Chapter 12.4.2 JLS 描述了详细的初始化过程,它负责在多线程环境中初始化类。

关于java - 类初始化和同步类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4623484/

相关文章:

java - HashMap成员的并发修改

java - 使用 Java 构建报告

提取标签间数据的Java正则表达式

java - 从 .NET 使用 Java Web 服务

c# - 为什么 C# 中没有并发集合?

c++ - google/dense_hash_map的线程安全

缩放线程运行时的 C++ 并发问题

java - 如何从 Firestore 获取数组内的映射值?

java - websphere 应用程序服务器处理多少个并发请求(WAS 8.0)?

c++ - 原子比较交换,但基于设置的标志,而不是平等?