Multithreading is a very important knowledge point in Java. Here, the editor summarizes Java Thread multithreading to you, which is very useful. I hope you can master it.
1. The life cycle of a thread and the five basic states
Regarding the life cycle of threads in Java, let’s first look at the following classic picture:
The above figure basically covers the important knowledge points of multi-threading in Java. Once you master the knowledge points in the above figure, you will basically master the multi-threading in Java. Mainly including:
Java threads have five basic states
New state (New): When a thread object pair is created, it enters a new state, such as: Thread t = new MyThread();
Ready state (Runnable): When the start() method of the thread object (t.start();), the thread enters the ready state. A thread in the ready state just means that the thread is ready and is waiting for the CPU to schedule execution at any time, not that the thread will execute immediately after t.start() is executed;
Running state: When the CPU starts to schedule threads in the ready state, the thread can be truly executed, that is, it enters the running state. Note: The ready state is the only entry to the running state, that is, if a thread wants to enter the running state to execute, it must first be in the ready state;
Blocked state: For some reason, a thread in the running state temporarily gives up its use of the CPU and stops execution. At this time, it enters the blocking state. It will not have the chance to be called by the CPU again to enter the running state.
According to the reasons for blocking, blocking states can be divided into three types:
1. Waiting for blocking: The thread in the running state executes the wait() method to make the thread enter the waiting for blocking state;
2. Synchronized blocking-- The thread fails to acquire the synchronized synchronization lock (because the lock is occupied by other threads), and it will enter the synchronized blocking state;
3. Other blocking--The thread will enter a blocking state by calling sleep() or join() of the thread or issuing an I/O request. When the sleep() state timed out, join() waited for thread to terminate or timed out, or I/O processing was completed, the thread re-entered to the ready state.
Dead: The thread has finished executing or exits the run() method due to an exception, and the thread ends its life cycle.
2. Creation and startup of Java multithreads
There are three basic forms of thread creation in Java
1. Inherit the Thread class and override the run() method of the class.
class MyThread extends Thread {private int i = ;@Overridepublic void run() {for (i = ; i < ; i++) {System.out.println(Thread.currentThread().getName() + " " + i);}}} public class ThreadTest {public static void main(String[] args) {for (int i = ; i < ; i++) {System.out.println(Thread.currentThread().getName() + " " + i); if (i == ) {Thread myThread = new MyThread(); // Create a new thread myThread This thread enters the new state Thread myThread = new MyThread(); // Create a new thread myThread This thread enters the new state myThread.start(); // Call the start() method to make the thread enter the ready state myThread.start(); // Call the start() method to make the thread enter the ready state }}}} As shown above, inherit the Thread class and override the run() method, a new thread class MyThread is defined, where the method body of the run() method represents the task that the thread needs to complete, and is called the thread execution body. When creating this thread class object, a new thread is created and enters the new thread state. By calling the start() method referenced by the thread object, the thread enters the ready state. At this time, the thread may not be executed immediately, depending on the CPU scheduling timing.
2. Implement the Runnable interface and override the run() method of the interface. The run() method is also a thread execution body, create an instance of the Runnable implementation class, and use this instance as the target of the Thread class to create a Thread object. The Thread object is the real thread object.
class MyRunnable implements Runnable {private int i = ;@Overridepublic void run() {for (i = ; i < ; i++) {System.out.println(Thread.currentThread().getName() + " " + i);}}} public class ThreadTest {public static void main(String[] args) {for (int i = ; i < ; i++) {System.out.println(Thread.currentThread().getName() + " " + i); if (i == ) {Runnable myRunnable = new MyRunnable(); // Create an object of Runnable implementation class Thread thread = new Thread(myRunnable); // Use myRunnable as a Thread target to create a new thread Thread thread = new Thread(myRunnable);thread.start(); // Call the start() method to make the thread enter the ready state thread.start();}}}} I believe that everyone is familiar with the above two ways to create new threads. So what is the relationship between Thread and Runnable? Let’s first look at the following example.
public class ThreadTest {public static void main(String[] args) {for (int i = ; i < ; i++) {System.out.println(Thread.currentThread().getName() + " " + i);if (i == ) {Runnable myRunnable = new MyRunnable();Thread thread = new MyThread(myRunnable);thread.start();}}}}class MyRunnable implements Runnable {private int i = ;@Overridepublic void run() {System.out.println("in MyRunnable run");for (i = ; i < ; i++) {System.out.println(Thread.currentThread().getName() + " " + i);}}}class MyThread extends Thread {private int i = ;public MyThread(Runnable runnable){super(runnable);}@Overridepublic void run() {System.out.println("in MyThread run");for (i = ; i < ; i++) {System.out.println(Thread.currentThread().getName() + " " + i);}}} Similarly, the same is true for creating threads that implement the Runnable interface, the difference is that
Thread thread = new MyThread(myRunnable);
So can this method successfully create a new thread? The answer is yes. As for the thread execution body at this time, is the run() method in the MyRunnable interface or the run() method in the MyThread class? Through output, we know that the thread execution body is the run() method in the MyThread class. In fact, the reason is very simple, because the Thread class itself also implements the Runnable interface, and the run() method is first defined in the Runnable interface.
public interface Runnable {public abstract void run();} Let's take a look at the implementation of the run() method in the Runnable interface in the Thread class:
@Overridepublic void run() {if (target != null) {target.run();}} That is to say, when executing the run() method in the Thread class, the run() method in the target will be determined first. If it exists, the run() method in the target is executed, that is, the run() method in the class that implements the Runnable interface and overwrites the run() method. However, in the columns given above, due to the existence of polymorphism, the run() method in the Thread class is not executed at all, but the runtime type, that is, the run() method in the MyThread class is directly executed.
3. Create threads using Callable and Future interfaces. Specifically, it creates an implementation class for the Callable interface and implements the clall() method. And use the FutureTask class to wrap the Callable implementation class object, and use this FutureTask object as the target of the Thread object to create a thread.
It seems a bit complicated, but it will be clear if you look at an example directly.
public class ThreadTest {public static void main(String[] args) {Callable<Integer> myCallable = new MyCallable(); // Create MyCallable object FutureTask<Integer> ft = new FutureTask<Integer>(myCallable); //Use FutureTask to wrap MyCallable object for (int i = ; i < ; i++) {System.out.println(Thread.currentThread().getName() + " " + i); if (i == ) {Thread thread = new Thread(ft); //FutureTask object creates a new thread as a target of the Thread object thread.start(); //Thread enters the ready state}}System.out.println("Main thread for loop execution completed..."); try {int sum = ft.get(); //Get the result returned by the call() method in the newly created new thread System.out.println("sum = " + sum);} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}}class MyCallable implements Callable<Integer> {private int i = ;// Unlike the run() method, the call() method has the return value @Overridepublic Integer call() {int sum = ;for (; i < ; i++) {System.out.println(Thread.currentThread().getName() + " " + i);sum += i;}return sum;}} First of all, we found that in implementing the Callable interface, the run() method is no longer the run() method, but the call() method. This call() method is the thread execution body and also has a return value! When creating a new thread, the MyCallable object is wrapped through FutureTask and is also used as a target for the Thread object. Then look at the definition of the FutureTask class:
public class FutureTask<V> implements RunnableFuture<V> {//....} public interface RunnableFuture<V> extends Runnable, Future<V> {void run();} Therefore, we found that the FutureTask class actually implements both Runnable and Future interfaces, which makes it have the dual characteristics of Future and Runnable. Through the Runnable feature, it can be used as a target of the Thread object, and the Future feature allows it to obtain the return value of the call() method in the newly created thread.
After executing this program, we find that sum = 4950 is always the last output. "The main thread for loop has been executed..." is likely to be output in the middle of the child thread loop. From the CPU's thread scheduling mechanism, we know that there is no problem with the output timing of "the main thread for loop has been executed...", so why will sum =4950 be output forever?
The reason is that when the child thread's call() method is obtained through the ft.get() method, when the child thread's method has not been executed yet, the ft.get() method will block until the call() method is executed before the return value can be obtained.
The above mainly explains three common thread creation methods. For the startup of threads, they are all called the start() method of the thread object. It is important to note that the start() method cannot be called twice on the same thread object.
III. Ready, Run and Death Status of Java Multithreading
The ready state is converted to the running state: when this thread gets the processor resource;
The running state is converted to the ready state: when this thread actively calls the yield() method or loses processor resources during running.
The running state is converted to the dead state: When the thread execution body is completed or an exception occurs.
It should be noted here that when the yield() method of the thread is called, the thread transitions from the running state to the ready state, but which thread in the ready state in the CPU is scheduled has a certain randomness. Therefore, it may occur that after the A thread calls the yield() method, the CPU still schedules the A thread.
Due to actual business needs, it is often encountered that a thread needs to be terminated at a specific opportunity to make it enter a dead state. The most common method at present is to set a boolean variable, and when the conditions are met, the thread execution body will be executed quickly. like:
public class ThreadTest {public static void main(String[] args) {MyRunnable myRunnable = new MyRunnable();Thread thread = new Thread(myRunnable);for (int i = ; i < ; i++) {System.out.println(Thread.currentThread().getName() + " " + i);if (i == ) {thread.start();}if(i == ){myRunnable.stopThread();}}}}class MyRunnable implements Runnable {private boolean stop;@Overridepublic void run() {for (int i = ; i < && !stop; i++) {System.out.println(Thread.currentThread().getName() + " " + i);}} public void stopThread() {this.stop = true;}}The above is a comprehensive analysis of Java Thread multi-threading that the editor introduced to you. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support to Wulin.com website!