Java 线程的状态
Java线程有六种状态:
初始(NEW)、运行(RUNNABLE)、阻塞(BLOCKED)、
等待(WAITING)、超时等待(TIMED_WAITING)、终止(TERMINATED)。
- 初始状态(NEW)
实现Runnable接口和继承Thread可以得到一个线程类,new一个实例出来,线程就进入了初始状态。 - 运行状态(RUNNABLE)
- 就绪状态(RUNNABLE之READY)
就绪状态只是说你资格运行,调度程序没有挑选到你,你就永远是就绪状态。
调用线程的start()方法,此线程进入就绪状态。
当前线程sleep()方法结束,其他线程join()结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入就绪状态。
当前线程时间片用完了,调用当前线程的yield()方法,当前线程进入就绪状态。
锁池里的线程拿到对象锁后,进入就绪状态。 - 运行中状态(RUNNABLE之RUNNING)
线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一的一种方式。
- 阻塞状态(BLOCKED)
阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态。 - 等待(WAITING)
处于这种状态的线程不会被分配CPU执行时间,它们要等待被显式地唤醒,否则会处于无限期等待的状态。 - 超时等待(TIMED_WAITING)
处于这种状态的线程不会被分配CPU执行时间,不过无须无限期等待被其他线程显示地唤醒,在达到一定时间后它们会自动唤醒。 - 终止状态(TERMINATED)
- 当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它终止了。这个线程对象也许是活的,但是它已经不是一个单独执行的线程。
- 线程一旦终止了,就不能复生。
- 在一个终止的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。
线程状态图:
对于几个阻塞状态的示例:
package demo;
import jdk.nashorn.internal.ir.Block;
import java.util.concurrent.TimeUnit;
public class ThreadDemo {
public static void main(String[] args) {
//该线程在main方法开始执行后就通过sleep(100)进入到 Timed_waiting 状态
new Thread(()->{
while(true){
try {
TimeUnit.SECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"thread_01").start();
//该线程因为Synchronized,进入WAITING状态
new Thread(()->{
while(true){
synchronized (ThreadDemo.class){
try {
ThreadDemo.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"thread_02").start();
//进入timed_waiting状态
new Thread(new BlockDemo(),"BlockDemo-01").start();
//进入block状态
new Thread(new BlockDemo(),"BlockDemo-02").start();
}
static class BlockDemo extends Thread{
@Override
public void run() {
synchronized (BlockDemo.class){
while(true){
try {
TimeUnit.SECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
我们通过jstack来查看他们的线程状态。
进入类目录,执行jps
D:\open_source\MyBatis\MyThread\target\classes\demo>jps
11776
20832 ThreadDemo
7856 Jps
21876 Launcher
27432 RemoteMavenServer36
执行 jstack 20832
D:\open_source\MyBatis\MyThread\target\classes\demo>jstack 20832
2023-02-20 00:30:44
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.351-b10 mixed mode):
"DestroyJavaVM" #18 prio=5 os_prio=0 tid=0x0000029032cf9000 nid=0x6a68 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"BlockDemo-02" #17 prio=5 os_prio=0 tid=0x000002904ff83800 nid=0x6f30 waiting for monitor entry [0x000000c5215ff000]
java.lang.Thread.State: BLOCKED (on object monitor)
at demo.ThreadDemo$BlockDemo.run(ThreadDemo.java:41)
- waiting to lock <0x000000076c8bca88> (a java.lang.Class for demo.ThreadDemo$BlockDemo)
at java.lang.Thread.run(Thread.java:750)
"BlockDemo-01" #15 prio=5 os_prio=0 tid=0x000002904ff78800 nid=0x18f0 waiting on condition [0x000000c5214fe000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:342)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at demo.ThreadDemo$BlockDemo.run(ThreadDemo.java:41)
- locked <0x000000076c8bca88> (a java.lang.Class for demo.ThreadDemo$BlockDemo)
at java.lang.Thread.run(Thread.java:750)
"thread_02" #13 prio=5 os_prio=0 tid=0x000002904ff78000 nid=0x4c28 in Object.wait() [0x000000c5213fe000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076c59bdf0> (a java.lang.Class for demo.ThreadDemo)
at java.lang.Object.wait(Object.java:502)
at demo.ThreadDemo.lambda$main$1(ThreadDemo.java:23)
- locked <0x000000076c59bdf0> (a java.lang.Class for demo.ThreadDemo)
at demo.ThreadDemo$$Lambda$2/1078694789.run(Unknown Source)
at java.lang.Thread.run(Thread.java:750)
"thread_01" #12 prio=5 os_prio=0 tid=0x000002904ff75000 nid=0x1c90 waiting on condition [0x000000c5212ff000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:342)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at demo.ThreadDemo.lambda$main$0(ThreadDemo.java:12)
at demo.ThreadDemo$$Lambda$1/1324119927.run(Unknown Source)
at java.lang.Thread.run(Thread.java:750)
各个线程的状态一目了然。