由静态块中的thread.join()引起的死锁 [英] Deadlock caused by thread.join() in a static block

查看:391
本文介绍了由静态块中的thread.join()引起的死锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I came across a deadlock scenario which can be summarized as the StaticDeadlock class shown below.

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

This simple program will freeze at o.getClass(). Here's my speculation of what happened, but can someone explain it better?

1)程序进入StaticDeadlock静态块

1) the program enters StaticDeadlock static block

2)线程开始

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

3) main thread is put in wait for thread to finish, hence can't finish the static block

4)在线程内访问 StaticDeadlock.o 但是StaticDeadlock的静态块还没有完成。因此程序会冻结吗?

4) inside thread it access StaticDeadlock.o but StaticDeadlock's static block is not finished yet. Hence the program freezes?

    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();
            }
        }

    }


推荐答案

是的,这就是它。新线程在访问静态成员之前等待 StaticDeadlock 的类初始值设定项完成。有关更多信息,请参阅 Java语言规范的第12.4.2节详细信息,特别是这些步骤:

Yes, that's pretty much it. The new thread is waiting for the class initializer of StaticDeadlock to complete before it accesses the static member. See section 12.4.2 of the Java Language Specification for more details, in particular these steps:



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

  1. Synchronize (§14.19) on the Class object that represents the class or interface to be initialized. This involves waiting until the current thread can obtain the lock for that object (§17.1).

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

If initialization is in progress for the class or interface by some other thread, then wait on this Class object (which temporarily releases the lock). When the current thread awakens from the wait, repeat this step.

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

If initialization is in progress for the class or interface by the current thread, then this must be a recursive request for initialization. Release the lock on the Class object and complete normally.

如果类或接口已初始化,则无需进一步操作。释放Class对象的锁定并正常完成。

If the class or interface has already been initialized, then no further action is required. Release the lock on the Class object and complete normally.


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

It won't even get past step 1 in the second thread, as the first thread has the lock and won't release it.

注意它没有调用导致问题的getClass() - 执行需要 o 值的任何将使第二个线程等到类初始化程序已经完成,当然不会发生,因为第一个线程正在等待第二个线程完成。

Note that it's not calling getClass() which causes the problem - doing anything which requires the value of o will make the second thread wait until the class initializer has completed, which of course won't happen because the first thread is waiting for the second thread to finish.

这篇关于由静态块中的thread.join()引起的死锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆