The article brief introduction

This article mainly focuses on the operation related to thread state control to analyze the principle of thread, such as thread interruption, thread communication, etc. The content is more, and may be divided into two articles

Content navigation

  • The implementation principle of thread start
  • Analysis of the implementation principle of thread stop
  • Why does an interrupt thread throw InterruptedException

First, the starting principle of threads

We have briefly analyzed the use of threads in the previous, by calling the thread start method to start the thread, the thread will call the running method to execute the business logic after starting, after the execution of the running method, the life cycle of the thread is terminated.

Many students will be confused when they first learn threads, why is starting a thread to call the start method, rather than run the method, this is a simple analysis, first briefly look at the definition of the start method

We see that calling the start method is actually calling a local method called START0 () to start a thread. First, START0 () is registered in the static block of the thread, as shown below

The registerNatives function is to register some local methods provided by the thread classes to use, such as IsAlive () of START0 (), currentThread (), and sleep (); These are all familiar methods.

The registerNatives local method is defined in the thread.cThread. c file, which defines the common data and operations on threads to be used by each operating system platform. The following is the full content of Thread.c

As you can see from this code, start0 () actually executes the JVM_StartThread method. By its name, it seems to start a thread at the JVM level. If this is the case, then at the JVM level, it must call the runtime method defined in Java. So let’s go ahead and find out. This file, this file need to download hot source to find. jvm.cpp

JVM_ENTRY is used to define the JVM_StartThread function, which creates a truly platform-specific local thread. In the spirit of breaking the pot and finding out what’s going on, keep looking for the JavaThread definition newJavaThread

The following code thread. CPP can be found at line 1558 in the hot source file

This method takes two parameters. The first parameter is the name of the function to which the thread will call the corresponding function after it is successfully created. The second one is the number of threads that are already in the current process and the last one we’ll focus on is actually creating a thread by calling the platform thread creation method. os::create_thread

The next step is to start the Thread by calling the Thread :: start (Thread * Thread) method in the thread. CPP file

CPP: JavaThread :: run () OS ::start_thread(Thread); CPP: JavaThread :: run ();

This method does a series of initializations and ends with a thread_main_inner method. What is the logic of this method

The first parameter passed in the :: JavaThread method represents the name of the function that will be called when the thread starts. this->entry_point()(this,this); Those who are interested in technology can join my learning circle :142019080

For those of you who haven’t gotten carsick yet, remember that the code we saw in the jvm.cpp file passed a thread at creation time, native_thread=newJavaThread(&thread_entry,sz); The entry function, so we find this function defined in jvm.cpp as follows

HPP: vmSymbols::run_method_name()run_method_name

So the conclusion is that the inside of the Java must create a thread after call setup method can really create a thread, this method will be called a virtual machine running a local thread, local thread creation will call the method that the current system create a thread to create, and will perform when the callback thread is run method of business logic processing

Two, the thread termination method and principle

The termination of a thread can be active or passive. Passive means that the thread exits abnormally or the execution of a running method is completed, and the thread will terminate automatically. The stop () method is not recommended for the simple reason that it does not guarantee that a thread’s resources will be released properly, i.e. it does not give the thread a chance to complete the release. On Linux, we use kill -9 to forcibly terminate a process. Thread.stop()

So how do you safely terminate a thread?

Let’s take a look at the following code, which demonstrates a proper way to terminate a thread. We’ll look at how this works later

There are two things to note in the code. In the main thread, the thread’s interrupt () method is called, and in the run method, the middle loop determines the identity of the thread’s interrupt. So let’s guess here, we maintain an interrupt flag in the thread, change the value of the interrupt flag in the method so that the method is not valid and the loop is broken, so the thread terminates after the execution of the execution method. Thread.currentThread().isInterrupted()thread.interrupt()

Those who are interested in technology can join my learning circle :142019080

The principle analysis of thread interrupt

Let’s see what the method does. Thread.interrupt ()

In this method, we call interrupt 0 (), which is a native method we saw earlier when we looked at startup methods. We won’t repeat the code here. Again, we go to the jVM.cpp file and find the definition of JVM_Interrupt

CPP: thread.cpp: thread.cpp: thread.interrupt (THR) : thread.cpp: thread.cpp

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * The os_linux. CPP file is used as an example

As you can see from the code analysis above, the thread.interrupt () method actually sets an interrupt status flag to true and wakes up the Thread with the unresident ParkEvent method.

  • A thread that is blocked synchronously will continue to attempt to acquire the lock after being woken up and may still be paroled if it fails
  • Before calling the park method of ParkEvent, the interrupt status of the thread is determined and, if true, the interrupt flag of the current thread is cleared
  • Wait, thread. sleep, and thread. join will throw InterruptedException

Object.wait, Thread.sleep, and Thread.join all throw InterruptedException. First, this exception means that a block has been interrupted by another thread. For example, after the Thread has invoked the interrupt () method, the status of the blocked Thread (Object. Wait, Thread.sleep, etc.) will be checked by is_interrupted. If the interrupt flag is true, the Thread will clear the interrupt flag. InterruptedException is then thrown

Note that throwing InterruptedException does not mean that the thread must terminate. Instead, it is up to the thread to tell it that an interrupted operation has occurred

  • The exception is caught without any processing
  • Throw an exception out
  • Stops the current thread and prints an exception message

Thread.sleep () ¶ Thread.sleep () ¶ Thread.sleep () ¶

For LINUX, the implementation is in the os_linux.cpp file as follows: is_interrupted()

Thread.sleep () : thread. sleep () : thread. sleep () : thread. sleep () : thread. sleep () If you looked carefully, you should be able to quickly find the code in the jvm.cpp file

Note the code with the Chinese comment above to check for is_interrupted status and throw an InterruptedException exception. At this point, we have analyzed the entire flow of the interruption.

Java thread interrupt identification

Now that you know what thread.interrupt does, it’s easy to look back at this code in Java. Since the former set an interrupt flag to true, this method returns true, so not meeting the loop criteria causes the loop to exit. Thread.currentThread().isInterrupted()isInterrupted()

It is important to note that the thread interrupt identifier is reset in two ways. The first is the aforementioned InterruptedException. The other is to reset the interrupt flag of the current Thread via thread.interrupted ().

Those who are interested in technology can join my learning circle :142019080