本文介绍了类初始化死锁机制说明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找到了文章( https://habr.com/company/odnoklassniki/blog/255067/)来自@apangin( 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个线程:

线程_1正在创建A的实例

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

这是对类的首次访问,因此它可能导致并发类A和B的初始化.

下一步对我来说还不清楚.你能解释一下吗?

解决方案

JVM规范§5.5详细描述了类初始化过程.它由12个步骤组成.

在第6步中,将该类标记为当前线程正在进行初始化".

因此,Thread_1开始初始化类A,并将其标记为由Thread_1初始化.类似地,类B被标记为由Thread_2初始化.

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

A的静态初始化器创建B的实例,该实例尚未完全初始化,因此Thread_1(正在初始化A的过程中)递归地启动初始化B的过程. /p>

在该过程的第2步中,它检测到类B正在通过不同的线程和块进行初始化.

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

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

I found article(https://habr.com/company/odnoklassniki/blog/255067/) from the @apangin(https://stackoverflow.com/users/3448419/apangin) on my native langugage but I am not able to understand it. Explanation is very concise

Let's consider that code:

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();
}

You could try to run that code. On my pc it leads to deadlockwith 75% probability/

So we have 2 threads:

Thread_1 is creating instance of A

Thread_2(main thread) is creating instance of B

It is first access to class so it leads(might lead) to concurrent classes A and B initialization.

Next step is not clear for me. Could you explain it?

解决方案

JVM Specification §5.5 describes class initialization procedure in detail. It consists of 12 steps.

At step 6 the class is marked as "in progress of initialization by the current thread".

So Thread_1 starts initializing class A and marks it as being initialized by Thread_1. Similarly class B is marked as being initialized by Thread_2.

At step 9 the static initializer is invoked.

The static initializer of A creates an instance of B, which is not yet fully initialized, so Thread_1 (while in progress of initializing A) recursively starts the procedure of initializing B.

At step 2 of the procedure it detects that class B is in progress of initialization by different thread and blocks.

Symmetrically Thread_2 starts initialization of A, detects that it is already being initialized by different thread and also blocks at step 2. Both threads are blocked waiting for each other.

Note: the class is marked as fully initialized and notifies other threads after successful invocation of static initializer, which never happens in this case.

这篇关于类初始化死锁机制说明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 17:16