开发者

Deadlock caused by thread.join() in a static block

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

This simple program will fre开发者_开发问答eze at o.getClass(). Here's my speculation of what happened, but can someone explain it better?

1) the program enters StaticDeadlock static block

2) thread starts

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

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

    }


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. 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).

  2. 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.

  3. 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.

  4. 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.

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

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜