我在我的母语中从 @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 步,该类被标记为“当前线程正在进行初始化”。
- 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 步,调用静态初始化程序。
- Next, execute the class or interface initialization method of C.
A
的静态初始化程序创建了 B
的实例,该实例尚未完全初始化,因此 Thread_1
(在初始化过程中) A
)递归地开始初始化B
的过程。
在该过程的第 2 步,它检测到类 B
正在由不同的线程和 block 进行初始化。
- 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处阻塞。两个线程都被阻塞等待对方。
注意:该类被标记为完全初始化,并在成功调用静态初始化程序后通知其他线程,在这种情况下永远不会发生这种情况。
- 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/