...
Code Block | ||
---|---|---|
| ||
public class Lazy { private static boolean flag = falseint number; static { Thread t = new Thread(new Runnable() { public void run() { // Initialize, for example, a database connection flagLazy.this.number = true42; } }); t.start(); try { t.join(); } catch(InterruptedException ie) { throw new AssertionError(ie); } // Other initialization } public static void main(String[] args) { System.out.println(flagnumber); } } |
Wiki Markup |
---|
The code in the {{static}} block is responsible for initialization, and starts a background thread. The background thread attempts to assign to the {{flagnumber}} but needs to wait before initialization of the {{Lazy}} class has finished. Remember that statically-initialized fields are guaranteed to be fully constructed before becoming visible to other threads (see [CON26-J. Do not publish partially initialized objects] for more info). Consequently the background thread must wait for the foreground thread to finish initialization before it may proceed. However, the {{Lazy}} class's main thread invokes the {{join()}} method which waits for the background thread to finish. This interdependency causes a class initialization cycle that results in a deadlock situation. \[[Bloch 05b|AA. Java References#Bloch 05b]\] |
...
Code Block | ||
---|---|---|
| ||
public class Lazy { private static boolean flag = falseint number; static { // Initialize, for example, a database connection flagthis.number = true42; } public static void main(String[] args) { System.out.println(flagnumber); } } |
Compliant Solution (ThreadLocal
)
...