Deadlock quiz
Wednesday, April 2, 2008 — Abel MuiñoSuppose 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?



Friday, April 4, 2008 at 16:34
Why is A_STRING and run() part of the class? It doesn’t seem like it’s getting called anywhere…
Friday, April 4, 2008 at 16:40
run() is called from Thread.start(), since the class implements Runnable (Lines 17, 1
Monday, April 7, 2008 at 15:49
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?
Tuesday, April 8, 2008 at 08:22
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).
Thursday, April 10, 2008 at 09:53
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.
Thursday, April 10, 2008 at 19:52
I’ve posted an explanation in a new post.