在另一个线程完成静态初始化(类加载)之前,线程是否可以进入静态方法?

时间:2017-12-11 11:52:24

标签: java multithreading deadlock static-initializer

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

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

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

1 个答案:

答案 0 :(得分:1)

不,一个类只能通过一个线程初始化一次。如果另一个线程访问同一个类,那么当初始化完成时,这个会阻塞。