java - 类初始化死锁机制解释

标签 java multithreading jvm initialization deadlock

我在我的母语中从 @apangin( https://habr.com/company/odnoklassniki/blog/255067/ ) 找到了文章( https://stackoverflow.com/users/3448419/apangin ),但我无法理解它。解释很简洁

让我们考虑一下该代码:

static class A {
    static final B b = new B();
}

static class B {
    static final A a = new A();
}

public static void main(String[] args) {
    new Thread(A::new).start();
    new B();
}

您可以尝试运行该代码。在我的电脑上,它有 75% 的概率导致死锁/

所以我们有 2 个线程:

Thread_1 正在创建 A 的实例

Thread_2(主线程)正在创建 B 的实例

这是对类的第一次访问,因此它导致(可能导致)并发的类 A 和 B 初始化。

下一步对我来说并不清楚。能解释一下吗?

最佳答案

JVM Specification §5.5详细描述了类的初始化过程。它由 12 个步骤组成。

在第 6 步,该类被标记为“当前线程正在进行初始化”。

  1. Otherwise, record the fact that initialization of the Class object for C is in progress by the current thread, and release LC.

因此,Thread_1 开始初始化类 A 并将其标记为由 Thread_1 初始化。同样,类 B 被标记为由 Thread_2 初始化。

在第 9 步,调用静态初始化程序。

  1. Next, execute the class or interface initialization method of C.

A 的静态初始化程序创建了 B 的实例,该实例尚未完全初始化,因此 Thread_1 (在初始化过程中) A)递归地开始初始化B的过程。

在该过程的第 2 步,它检测到类 B 正在由不同的线程和 block 进行初始化。

  1. If the Class object for C indicates that initialization is in progress for C by some other thread, then release LC and block the current thread until informed that the in-progress initialization has completed, at which time repeat this procedure.

对称地Thread_2开始初始化A,检测到它已经被不同的线程初始化,并且也在步骤2处阻塞。两个线程都被阻塞等待对方。

注意:该类被标记为完全初始化,并在成功调用静态初始化程序后通知其他线程,在这种情况下永远不会发生这种情况。

  1. If the execution of the class or interface initialization method completes normally, then acquire LC, label the Class object for C as fully initialized, notify all waiting threads, release LC, and complete this procedure normally.

关于java - 类初始化死锁机制解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53682182/

相关文章:

java - 有没有办法将 class/jar 文件的内容传递到 JVM,而不将它们显式保存在磁盘上?

java - 启动 Jboss 服务器时出错 : Exception in thread "pool-6-thread-5" java. lang.OutOfMemoryError: PermGen space

c# - Lucas Lehmer 优化

java - 在 Java 虚拟机中处理信号

elasticsearch - 如何从正在运行的 JVM 中捕获堆转储

c++ - C++中的多线程效率

java - 迭代器如何绑定(bind)到集合接口(interface)

java - 如何获取给定范围内的文件字节?

java - 在 Java EE 6 中生成激活 url

c - 多任务如何让工作线程在调用无限循环函数后获得控制权