0

假设我们有以下类和两个线程 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() 并在持有 A 的锁的同时要求 B 的锁。

4) t2 继续执行 A.aMeth() 并要求 A 锁定,同时持有 B 锁定。

这会导致死锁。但在我的情况下 t2 实际上进入aMeth() 并在访问静态成员时被阻止str。所以我想知道线程在特殊情况下初始化之前是否有可能进入静态方法。

在我的测试运行中,t2 总是按预期在 A.aMeth() 处被阻止,因此是否存在任何可以进入并被阻止的极端情况str,JIT 优化,如方法内联等。

4

1 回答 1

1

不,一个类只能由一个线程初始化一次。如果另一个线程访问同一个类,这个类将在初始化完成时阻塞。

于 2017-12-11T12:28:37.640 回答