假设我们有以下类和两个线程 t1,t2。
public class A {
static String str = "abc";
static {
B.bMeth();
}
static void aMeth() {
System.out.println("A::meth()");
str = "abc2";
}
static void aSomeMeth() {}
}
public class B {
static {
A.aMeth();
}
static void bMmeth() {}
static void bSomeMeth() {}
}
以下是死锁发生的顺序:
1) t1 执行 A.aSomeMeth(),它获取 A 的类加载锁。
2) t2 执行 B.bSomeMeth(),它获取 B 的类加载锁。
3) t1 继续执行 B.bMeth() 并要求对 B 进行锁定,同时保持对 A 的锁定。
4) t2 继续执行 A.aMeth() 并需要对 A 进行锁定,同时对 B 保持锁定。
这会导致死锁。但在我的例子中,t2 实际上进入了 aMeth(),并且在访问静态成员 str 时被阻止。所以我想知道在特殊情况下线程是否可以在初始化之前进入静态方法。
在我的测试运行中,t2 总是按预期在 A.aMeth() 处被阻止,因此是否存在任何极端情况,它可以进入它并在 str
上被阻止,JIT 优化(例如方法)内联等
最佳答案
不可以,一个类只能由一个线程初始化一次。如果另一个线程访问同一个类,则该线程将在初始化完成时阻塞。
关于java - 一个线程可以在另一个线程完成静态初始化(类加载)之前进入静态方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47752358/