【问题标题】:Deadlock caused by thread.join() in a static block静态块中由 thread.join() 引起的死锁
【发布时间】:2011-07-14 06:17:54
【问题描述】:

我遇到了一个死锁场景,可以概括为如下所示的 StaticDeadlock 类。

这个简单的程序将在 o.getClass() 处冻结。这是我对发生的事情的猜测,但有人可以更好地解释一下吗?

1)程序进入StaticDeadlock静态块

2) 线程开始

3) 主线程等待线程完成,因此无法完成静态块

4) 在 thread 内部它访问 StaticDeadlock.o 但 StaticDeadlock 的静态块尚未完成。因此程序冻结了?

    public class StaticDeadlock
    {
        private static final Object o = new Object();

        static {
            MyThread thread = new MyThread();
            thread.start();

            try {
                thread.join();
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public static void main (String[] args)
        {
            System.out.println("all is well.");
        }

        static class MyThread extends Thread
        {
            @Override
            public void run ()
            {
                System.out.println("inside mythread");
                o.getClass();
            }
        }

    }

【问题讨论】:

    标签: java multithreading deadlock


    【解决方案1】:

    是的,差不多就是这样。新线程在访问静态成员之前正在等待StaticDeadlock 的类初始化程序完成。请参阅section 12.4.2 of the Java Language Specification 了解更多详情,尤其是以下步骤:

    1. 在表示要初始化的类或接口的 Class 对象上同步(第 14.19 节)。这涉及等到当前线程可以获取该对象的锁(第 17.1 节)。

    2. 如果其他线程正在对类或接口进行初始化,则等待这个 Class 对象(它会暂时释放锁)。当当前线程从等待中唤醒时,重复此步骤。

    3. 如果当前线程正在对类或接口进行初始化,则这必须是初始化的递归请求。解除对Class对象的锁定,正常完成。

    4. 如果类或接口已经初始化,则不需要进一步的操作。解除对Class对象的锁定,正常完成。

    它甚至不会通过第二个线程中的第 1 步,因为第一个线程拥有锁并且不会释放它。

    请注意,导致问题的不是调用getClass() - 执行需要o 值的任何事情 将使第二个线程等待类初始化程序完成,这当然会赢'不会发生,因为第一个线程正在等待第二个线程完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      • 2018-07-28
      相关资源
      最近更新 更多