Java thread state complete analysis tutorial

Introduction

Java threads have 6 states, namely NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED. This article explains the process of thread state change and uses code to demonstrate which methods can be invoked to make a thread change state.

1. Briefly describe 6 thread state definitions

The various state definitions of the thread are listed here for your convenience, and will be explained in detail below.

  1. Initial( NEW): The state when a thread object is newly created, but the start() method has not been called.

  2. Running ( RUNNABLE): In Java threads, the two states of ready ( ready) and running ( running) in the operating system are collectively referred to as "runnable" RUNNABLEstates.
    After the thread object is created, other threads (such as mainthreads) call the start()methods of the object. The thread in this state is in the runnable thread pool, waiting to be selected by thread scheduling to obtain the right to use the CPU, and it is in the ready state ( ready). runningA thread in the ready state becomes the running state ( ) after obtaining a CPU time slice . So calling the start()method does not mean that the thread will execute immediately.

  3. Blocking ( BLOCKED): Indicates that the thread is blocked on the lock. Only in a Synchronizedcode block, and no lock state is acquired.
    Waiting for other threads to release the exclusive lock.

  4. Waiting ( WAITING): A thread entering this state needs to wait for some specific action (notification or interruption) from other threads.
    Wait indefinitely. Waiting to be woken up.

  5. Timeout waiting ( TIMED_WAITING): This state is different from WAITINGthat it can return by itself after a specified time
    . Waiting with a time limit. Waiting for a set period of time.

  6. Terminate ( TERMINATED): Indicates that the thread has finished executing.
    The thread will enter this state after the normal execution of the thread is completed. Or run()an exception occurs in the method, and the thread terminates unexpectedly.

2. Detailed analysis of thread status

1. Initial state

When a thread is created, the thread enters the initial state. How to create threads, refer to the article: "Two Ways of Creating Threads in Java Official Documents and Analysis of Advantages and Disadvantages" .

2.1 Running state (ready state)

就绪状态(ready)只是表名线程有资格运行,若调度程序没有挑选到此线程,此线程将永远是就绪状态。

How can I get to the ready state?

① When the start()method of the thread is called, the thread enters the ready state.

② When the thread finishes executing the sleep()method, the thread enters the ready state.

③ After the other thread execution Join()method ends, the thread enters the ready state.

④Wait for the user input to complete, a thread gets the object lock, and the thread enters the ready state.

⑤ When the time slice of the current thread is used up, the method of the current thread is called yield(), and the current thread enters the ready state.

⑥ After the thread in the lock pool gets the object lock, it enters the ready state.

2.2. Running state (running state)

The running state (running) is that the thread scheduler selects a thread to execute from the runnable pool.

How can I enter the running state?

Only any thread in the ready state can be selected by the CPU for execution, and the programmer cannot manually specify which thread to run. This is the only way for a thread to enter the running state.

Note: It is mentioned here that "the choice of which thread to run is determined by the CPU itself", which is the official answer given by Java: The choice is arbitrary and occurs at the discretion of the implementation. Translation: "This choice is arbitrary and at the discretion of the executor".

The code demonstrates the NEW and RUNNABLE states

public class ShowThreadRunnableStatus implements Runnable {
	public static void main(String[] args) {
		Thread thread = new Thread(new ShowThreadRunnableStatus());
		System.out.println("创建完线程的状态:" + thread.getState());
		thread.start();
		System.out.println("启动后线程的状态:" + thread.getState());
		try {
			// 线程执行2毫秒以后,打印一下状态
			Thread.sleep(2);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("线程执行中的线程状态:" + thread.getState());
	}

	@Override
	public void run() {
		for (int i = 0; i < 800; i++) {
			System.out.println(i);
		}

	}
}

operation result:

创建完线程的状态:NEW
启动后线程的状态:RUNNABLE
0
1
2
3
打印结果省略……
263
264
265
线程执行中的线程状态:RUNNABLE
266
267
268
打印结果省略……

3. Blocking state

I often hear the term "thread blocking", but what exactly is blocking?

BLOCKED或WAITING或TIME_WAITING这三种统称为堵塞状态。因为这三种状态,都让线程进入等待状态,而不再是运行状态,所以统称为堵塞状态。

阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态,即还没有真正运行Synchronized修饰的代码时的状态。

In layman's terms, the thread wants to execute the content of the Synchronized code block, but does not get the lock. At this time, the waiting state is the blocked state.

Life example: It
's like when you line up for shopping, it's a state of jam when it's coming to you right away but not yet. You're stuck before the shopping window, and when it's your turn to buy and pay, that's in the running.

4. Wait state

等待状态即执行了`wait()`方法后,将锁释放,进入无尽的等待当中,直到被`notify()`方法唤醒。

A thread in this state will not be allocated execution time by the CPU, and will wait forever if it is not explicitly woken up.

Life example: It
's like the interviewer asks you to go back and wait for news after the interview is over. If the interviewer does not take the initiative to contact you, it means that you have no chance, and you can only wait indefinitely. Interviewers generally won't call to tell you that you didn't pass the interview. At this time, the interview for this position has fallen into endless waiting, which is the waiting state.

The code shows the WAITING state

public class ShowThreadWaitingStatus implements Runnable {

	public static void main(String[] args) {
		ShowThreadWaitingStatus runnable = new ShowThreadWaitingStatus();
		Thread thread1 = new Thread(runnable);
		thread1.start();
		Thread thread2 = new Thread(runnable);
		thread2.start();
		try {
			Thread.sleep(3);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		// 打印出TIME_WAITING,原因是:Thread.sleep(1000);
		System.out.println("线程1的状态:" + thread1.getState());
		// 打印出BLOCKED,因为线程2拿不到method的方法锁
		System.out.println("线程2的状态:" + thread2.getState());
		try {
			Thread.sleep(1400);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		// 打印出WAITING,因为wait()方法,使线程进入到WAITING状态
		System.out.println("线程1的状态:" + thread1.getState());
		// 打印出TIME_WAITING,因为Thread.sleep(1400)方法,使线程进入到TIME_WAITING状态
		System.out.println("线程2的状态:" + thread2.getState());
	}

	@Override
	public void run() {
		method();
	}

	/**
	 *
	 */
	private synchronized void method() {
		try {
			Thread.sleep(1000);
			wait();
			//System.out.println(Thread.currentThread().getName() + ",状态是:" + Thread.currentThread().getState());
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

Running results: (results may be different on different JVM machines)

线程1的状态:TIMED_WAITING
线程2的状态:BLOCKED
线程1的状态:WAITING
线程2的状态:TIMED_WAITING

5. Timeout status

等待状态即执行了`wait(timeout)`方法后,将锁释放,进入等待当中,直到被`notify()`方法唤醒或者时间超过timeout设置的毫秒数后,自动唤醒。

The difference between the waiting state and the timeout waiting state is that a timeout period can be set for timeout waiting. If it exceeds this time and is not awakened, it will not wait and will be automatically awakened.

线程何时被唤醒我们无法控制,但我们可以修改和优化线程执行时间。

Don't worry about what we can't control. When writing code, we need to do things within the boundaries. We can optimize the code and delete unnecessary logic to optimize the execution speed of the thread.

Life example:
Just like being stopped by a teacher, if the math teacher left the classroom in a hurry and forgot to cancel the punishment, then you can only be stopped until the bell rang, even if the math teacher didn't let you sit down , you can also lift the seal by yourself, sit and study the next language class, that is, wake up after the designated time.

The code demonstrates the TIME_WAITING and BLOCKED states

public class ShowThreadBlockedStatus implements Runnable {

	public static void main(String[] args) {
		ShowThreadBlockedStatus runnable = new ShowThreadBlockedStatus();
		Thread thread1 = new Thread(runnable);
		thread1.start();
		Thread thread2 = new Thread(runnable);
		thread2.start();
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		//线程1的状态:TIMED_WAITING,因为:Thread.sleep(1000)
		System.out.println("线程1的状态:" + thread1.getState());
		// 打印出BLOCKED,因为拿不到method的方法锁
		System.out.println("线程2的状态:" + thread2.getState());
	}

	@Override
	public void run() {
		method();
	}

	/**
	 *
	 */
	private synchronized void method() {
		try {
			Thread.sleep(1000);
			//System.out.println(Thread.currentThread().getName() + ",状态是:" + Thread.currentThread().getState());
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

operation result:

线程1的状态:TIMED_WAITING
线程2的状态:BLOCKED

6. Termination state

How to enter the terminated state

①. When the thread run()method is completed, or the main()method of the main thread is completed, the state of the thread becomes the terminated state at this time. Even if the thread object is still alive and has not been garbage collected, once the thread is terminated, it cannot be resurrected.

Note: If it is called again after a terminated thread start(), an exception will be thrown java.lang.IllegalThreadStateException, indicating that the thread cannot be resurrected from the dead.

run()If an exception is thrown in the thread method, it will enter the termination state.

3. Changes in thread state and execution order

insert image description here

Thread state change flow chart

1. Only three states in positive sequence

Threads can only go from NEWto RUNNABLEto TERMINATED, this is the order that cannot be reversed (the leftmost column in the above figure). If you still want to execute NEW, you can only recreate the thread, and the original thread will be recycled by the JVM.

2. Three states that can be executed in reverse

Thread RUNNABLEarrival WAITING, RUNNABLEarrival TIME_WAITING, and RUNNABLEarrival BLOCKEDcan be executed in both directions.

3. The thread state cannot be skipped and executed

The thread state cannot be jumped, the NEWstate cannot be jumped to BLOCKED, WAITING, and the TIME_WAITINGstate is executed (), and NEWit cannot be directly jumped to the TERMINATEDstate.

Summarize

This article explains the definitions of the six states of the thread in detail, demonstrates and analyzes the meaning of the various states from the code level, and explains the thread execution process and precautions. For other knowledge related to threads, see Supplementary Issues. If you like this article, please like, subscribe, and follow.

Supplementary reference materials:
For a series of tutorials on multithreading, synchronized关键字, , wait()and notify()methods, please refer to the following articles:

"Two Ways and Principles of Synchronized Implementing Class Locks in Java"

"Two ways and principle analysis of synchronized implementation of object lock in Java"

"Java multi-threaded wait() and notify() series method usage tutorial"

"The use of notifyAll() method in Java multithreading tutorial"

"Java two threads alternately print odd and even numbers (two methods comparison)"

"Analysis and Code Verification of Synchronized Reentrancy and Uninterruptibility in Java"

"Eight usage scenarios of Java multi-threaded access to Synchronized synchronization methods"

"Two Ways of Creating Threads in Java Official Documents and Analysis of Advantages and Disadvantages"

"Thread-safe and thread-unsafe analysis and examples in Java"

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324079809&siteId=291194637