Multithreading traps (the Code in all static initialization blocks is not necessarily a class initialization operation)

Source: Internet
Author: User

Http://blog.csdn.net/bornforit/article/details/6898929

 

Let's look at a program first:
[Java]View plaincopyprint?
 
 
  1. <Span style = "font-family: simhei"> public class staticthreadinit {
  2. Static {
  3. Thread t = new thread (){
  4. Public void run (){
  5. System. Out. println ("Enter the run method ");
  6. System. Out. println ("1 ------" + website );
  7. Website = "www.leegang.org ";
  8. System. Out. println ("2 ------" + website );
  9. System. Out. println ("exit the run method ");
  10. }
  11. };
  12. T. Start ();
  13. Try {
  14. T. Join ();
  15. } Catch (interruptedexception e ){
  16. E. printstacktrace ();
  17. }
  18. }
  19. Static string website = "www.crazyit.org ";
  20. Public static void main (string ARGs []) {
  21. System. Out. println ("Main:" + staticthreadinit. website );
  22. }
  23. } </Span>
Public class staticthreadinit {static {thread t = new thread () {public void run () {system. out. println ("Enter the run method"); system. out. println ("1 ------" + website); website = "www.leegang.org"; system. out. println ("2 ------" + website); system. out. println ("exit the run method") ;}}; T. start (); try {T. join ();} catch (interruptedexception e) {e. printstacktrace () ;}} static string website = "www.crazyit.org"; public static void main (string ARGs []) {system. out. println ("Main:" + staticthreadinit. website );}}

Running result:

Enter the run Method
Why? Why is the website value not printed? Next we will analyze the execution process of this program:
The main thread tries to access the value of staticthreadinit. Website. At this time, staticthreadinit has not been initialized, so the main thread starts to initialize the class. The initialization process consists of two steps: one is to allocate memory for all static fields of the class, and the other is to call the code of the static initialization block to execute initialization. Therefore, the main thread first allocates memory space for the website field of the staticthreadinit class. At this time, the website value is null. Then, the main thread starts to execute the static initialization block of the staticthreadinit class. This code block creates and starts a new thread and calls the join () method of the new thread. This means that the main thread must wait until the execution of the new thread ends before it can be executed downward. After the new thread starts to execute, first execute system. Out. println ("Enter the run method"); code, which is the first line of output seen when the program is running. Then the program tries to execute system. Out. println (website); The problem arises. The staticthreadinit class is being initialized by the main thread, so the new thread will wait until the main thread finishes initialization of the staticthreadinit class. At this time, the deadlock condition is met: the two threads wait for each other to execute, so neither of them can be executed downward. So there is a deadlock when the program is executed, and the program cannot be executed.

The key cause of the deadlock is that the program calls T. Join (). The following analyzes the program running after T. Join () annotation:

Main: www.crazyit.org

Enter the run Method

1------www.crazyit.org

2------www.leegang.org

Exit the run Method

The execution process is as follows:

After the main thread enters the staticthreadinit static initialization, it also creates and starts a new thread. This time, the main thread does not wait for the new thread. At this time, the new thread is only in the ready state and has not yet entered the running state. The main thread continues the initialization operation. After the initialization operation is completed, the output statement in main can be completed. Next, the new thread enters the running state and runs the run method once. Obviously, the reason for the above running result is that after the start () method of a thread is called, the thread does not enter the running state immediately, and it will only remain in the ready state.

To change this state, call thread. Sleep () immediately after T. Start () to suspend the current program thread so that the new thread can immediately obtain the execution opportunity. The running result is as follows:

Enter the run Method

Main: www.crazyit.org

1------www.crazyit.org

2------www.leegang.org

Exit the run Method

The execution process is as follows:

When the main thread creates and starts a new thread, the main thread calls the thread. sleep () Suspends itself so that the new thread can get the execution opportunity. But when the new thread executes and outputs the website value, because the staticthreadinit class has not been initialized, the new thread has to give up the execution. The thread scheduler switches to the main thread again, and the mian thread completes website initialization. So far, the staticthreadinit class initialization is complete. Generally, the main thread will not immediately switch back to execute a new thread, and it will execute the first line of code in the main method.

There is a practical problem here: the multi-thread value assigned to the static field in the static initialization block is not an initial value at all. It is just a normal assignment. Let's look at the following code:
    [Java]View plaincopyprint?
  
  
  1. <Span style = "font-family: simhei"> <span style = "font-size: 16px"> public class staticthreadinit {
  2. Static {
  3. Thread t = new thread (){
  4. Public void run (){
  5. Website = "www.leegang.org ";
  6. }
  7. };
  8. T. Start ();
  9. Try {
  10. Thread. Sleep (1 );
  11. } Catch (interruptedexception e ){
  12. E. printstacktrace ();
  13. }
  14. }
  15. Final Static string website;
  16. Public static void main (string ARGs []) {
  17. System. Out. println ("Main:" + staticthreadinit. website );
  18. }
  19. } </Span>
public class StaticThreadInit {static {Thread t = new Thread() {public void run() {website = "www.leegang.org";}};t.start();try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}final static String website;public static void main(String args[]) {System.out.println("main:" + StaticThreadInit.website);}}

An error occurs when compiling the above program: you cannot specify a value for the final variable website.

From the error message above, we can see that the new thread started by the static initialization block cannot assign values to the website at all. This indicates that the assignment of the new thread to the website is not an initialization operation at all, it's just a normal assignment. This program teaches us that analyzing a program should not only stay on static code, but also grasp the running details of the program from the program execution process.

Do not think that all the code in the static initialization block must be a class initialization operation. The run method for starting a new thread in the static initialization block is only the thread execution body of the new thread, not a class initialization operation. Similarly, do not think that all the code in the non-static initialization block must be an object initialization operation. The run method for starting a new thread in the non-static initialization block is only the thread execution body of the new thread, it is not an object initialization operation.

 

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.