Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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

This simple program will freeze 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();
            }
        }

    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
240 views
Welcome To Ask or Share your Answers For Others

1 Answer

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...