Puzzle 85: Inertia Initialization

Source: Internet
Author: User

The following poor small class is too lazy, and even reluctant to use the usual method for initialization,
So it turned to the background thread. What will this program print? It is printed every time you run it.

public class Lazy {private static boolean initialized = false;static {Thread t = new Thread(new Runnable() {public void run() {initialized = true;}});t.start();try{t.join();}catch (InterruptedException e){throw new AssertionError(e);}}public static void main(String[] args){System.out.println(initialized);}}


Although a little strange, this program looks very intuitive. The static domain initialized is set at the initial time.
Is false. Then the main thread creates a background thread. The run method of this thread will initialize

Is set to true. After the main thread starts the background thread, it calls the join method and waits for its end.
When the background thread finishes running, there is no doubt that the value of initialized has been set to true.
If this is the only time, the main thread that calls the main method will print the value of initialized. For example
If so, will the program print true? If you run the program, you will find that it does not
It prints everything and it is suspended.
To understand the behavior of this program, we need to simulate its initialization details. When a thread accesses
When a member of a class, it checks whether the class has been initialized. When you ignore serious errors
In this case, there are four possible cases [JLS 12.4.2]:
• This class has not been initialized yet.
• This class is being initialized by the current thread: This is a recursive request for initialization.
• This class is being initialized by another thread rather than the current thread.
• This class has been initialized.
When the main thread calls the lazy. Main method, it checks whether the lazy class has been initialized. At this time, it
It is not initialized (Case 1), so the main thread will record that the current Initialization is in progress and start
This class is initialized. According to our previous analysis, the main thread will set the value of initialized
False: Creates and starts a background thread. The run method of this thread sets initialized
True. Then, the main thread waits for the execution of the background thread to complete. Now, interesting things begin.
The background thread calls its run method. Set lazy. initialized to true in this thread
Previously, it will also check whether the lazy class has been initialized. At this time, this class is being
Initialize a thread (Case 3 ). In this case, the current thread, that is, the background line
The class object will wait until the initialization is complete. Unfortunately, the one that is initializing
The thread, that is, the main thread, is waiting for the end of the background thread. Because the two threads are in the same phase
Wait for each other, and the program will be deadlocked ). That's all. Sorry. There are 2
Method to correct this program. So far, the best way is not to initialize the class.
Start any background thread: Sometimes, two threads are not better than one. More generally,
Class initialization should be as simple as possible. The 2nd method to correct this program is to keep the main thread waiting
Class initialization is completed before the background thread:

// Bad way to eliminate the deadlock. Complex and error pronepublic class Lazy {private static boolean initialized = false;private static Thread t = new Thread(new Runnable() {public void run() {initialized = true;}});static {t.start();}public static void main(String[] args){try{t.join();}catch (InterruptedException e){throw new AssertionError(e);}System.out.println(initialized);}}


Although this does eliminate deadlocks, it is a very bad idea. The main thread needs to wait
The background thread completes the work, but other threads do not need to do this. Once the main thread completes
Class initialization, other threads can use this class. This causes the initialized value to be
When it is set to false, other threads can observe it.
In short, waiting for a background thread during class initialization may cause a deadlock. The
The action sequence is as simple as possible. Automatic class initialization is recognized as a difficult problem in language design.
Designers have done a good job in this regard. If you write some complex class initialization code, a lot
In this case, you are throwing a rock on your feet.


Puzzle 85: Inertia Initialization

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.