Deadlock quiz

Suppose you have this class:

public class Singleton implements Runnable {
	public static final String A_STRING = "Hello World".toLowerCase();

	public static final Singleton INSTANCE = new Singleton();

	public static Singleton getInstance() {
		return INSTANCE;
	}

	private Singleton() {
		super();
		launchThread();
	}

	public void launchThread() {
		synchronized (this) {
			Thread t = new Thread(this);
			t.start();
			while (t.isAlive()) {
				try {
					wait(100);
				} catch (InterruptedException e) {
					// Interrupted.
				}
			}
		}
	}

	public void run() {
		System.out.println(A_STRING);
	}

	public static void main(String[] args) {
		Singleton.getInstance();
	}
}

If you run the main method, it hangs in a deadlock. Can you see the reason?

About these ads

  1. matthewsteele

    Why is A_STRING and run() part of the class? It doesn’t seem like it’s getting called anywhere…

  2. run() is called from Thread.start(), since the class implements Runnable (Lines 17, 18)

  3. matthewsteele

    I’ve been reading up on concurrency in Java all weekend, and I’m still no closer to figuring this out.

    Does it have to do with the object being locked is the class (since you’re performing synchronized() in a singleton), as opposed to an instance of the object?

    I give up. What’s the answer?

  4. Piotr Smolinski

    Consider slight modification:

    public static final String A = “Hello World”;
    public static final String B = “Hello World”.toLowerCase();

    (…)

    public void run() {
    System.out.println(A);
    System.out.println(B);
    }

    The code locks on System.out.println(B);
    If you remove also synchronized section from launchThread() and use Thread.sleep(100) the situation is the same.

    In my opinion this is due to different initialization of A and B. The first one is literal (compile-time constant) while the second one must be initialized. Therefore JVM delays B access until class is statically initialized (which happens when the thread ends).

  5. Allan Ramirez

    After t.start() is called, the caller thread would return and the other thread (t) would call run method.

    The other thread (t) cannot call run method because the caller thread still holds the lock. Therefore the other thread (t) will always be alive and the caller thread will be stucked to while block forever.






Follow

Get every new post delivered to your Inbox.

%d bloggers like this: