gpt4 book ai didi

java - 在java代码中获取死锁

转载 作者:行者123 更新时间:2023-11-30 08:35:56 25 4
gpt4 key购买 nike

我有以下三个类。

基础类.java

public class BaseClass {

static {
load();
}

public static void init() {
System.out.println("base init");
}

private static void load() {
System.out.println("In load method of base class");
DerivedClass dc = new DerivedClass();
System.out.println("Object creation done.");
}

}

派生类.java

public class DerivedClass extends BaseClass {

public DerivedClass() {
System.out.println("derived class constructor");
}

public static boolean isSynthetic(String _attr) {
return true;
}
}

Helper.java

public class Helper {

public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
BaseClass.init();
};
};
t.start();
System.out.println("calling static method of derived class..");
System.out.println(DerivedClass.isSynthetic("test"));
}

}

当我从 Helper.java 执行 main 方法时,我得到以下输出 -

calling static method of derived class..

In load method of base class

执行停止后,进程仍在运行。所以似乎有一些僵局,但我不明白为什么会这样。需要帮助。

最佳答案

当第一次引用 BaseClass 时,类加载器启动并想要设置要使用的类。所以它加载类并启动静态初始化 block

static {
load();
}

这会调用 load 方法,您会在其中尝试创建类型为 DerivedClass 的对象。这将首先尝试调用 super() 构造函数,即类 BaseClass 的方法 - 但 BaseClass 尚未完全初始化,因为它的静态初始化程序尚未完成 => 死锁。

编辑:根据您的评论,我做了更多的研究。其实,事情并没有我想的那么简单。 JVM 能够处理递归初始化,因此在单线程情况下没有问题。可以在 JVM 规范的第 5.5 节中找到类初始化过程的描述。

这里的罪魁祸首实际上是两个初始化进程之间的竞争条件。

线程 1 到达 DerivedClass.isSynthetic("test"),并开始初始化 DerivedClass

同时线程 2 到达 BaseClass.init() 并开始初始化 BaseClass

在初始化 DerivedClass 时,线程 1 认识到它必须初始化父类(super class)。由于 BaseClass 的初始化已经由线程 2 进行,线程 1 必须等待它完成。

在初始化 BaseClass 时,线程 2 到达 DerivedClass dc = new DerivedClass();。由于 DerivedClass 的初始化已经由线程 1 进行,线程 2 必须等待它完成。

所以实际上这是一个经典的死锁,其中两个线程试图以不同的顺序(BaseClass->DerivedClass 与 DerivedClass->BaseClass)进入两个关键代码路径(“类 X 的初始化”)并最终相互等待。

在适当的地方添加一些 Thread.sleep(100); 也会告诉您这确实是一个竞争条件。在我的测试中,有时尽管初始化期间存在循环依赖,但程序仍会成功完成。

关于java - 在java代码中获取死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37959532/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com