基础概念
Java线程在运行生命周期中的指定时刻只可能处于这6种不同状态的其中一个状态,分别是:
- NEW:初始状态,这是线程被创建出来但没有被调用
start()
。 - RUNNABLE:运行状态,线程被调用了
start()
等待运行的状态。 - BLOCKED:阻塞状态,等待
- WAITING:等待状态,表示该线程需要等待其他线程做出一些特定动作(通知或中断)
- TIME_WAITING:超时等待状态,可以在指定的时间后自行返回而不是像WAITING一样一直等待。
- TERMINATED:终止状态,表示该线程已经运行完毕。
具体生命周期为:
- 线程创建之后它将处于 NEW(新建) 状态,调用
start()
方法后开始运行,线程这时候处于 READY(可运行) 状态。可运行状态的线程获得了 CPU 时间片(timeslice)后就处于 RUNNING(运行) 状态。这里可能还有一个操作系统级别的阻塞状态(例如,线程执行长时间文件读写操作) - 当线程执行
wait() join()
等方法之后,线程进入 WAITING(等待) 状态。进入等待状态的线程需要依靠其他线程的通知才能够返回到运行状态。 - TIMED_WAITING(超时等待) 状态相当于在等待状态的基础上增加了超时限制,比如通过
sleep(long millis)
方法或wait(long millis)
方法可以将线程置于 TIMED_WAITING 状态。当超时时间结束后,线程将会返回到 RUNNABLE 状态。 - 当线程进入
synchronized
方法/块,但是锁被其它线程占有,这个时候线程就会进入 BLOCKED(阻塞) 状态。 - 线程在执行完了
run()
方法之后将会进入到 TERMINATED(终止) 状态。
注意
图中的RUNNABLE种还有一个阻塞状态,这并不是Java线程中的阻塞状态,而是操作系统级别的阻塞状态。那会在什么情况下出现呢?比如耗时的文件IO时,操作系统其实会将线程置为阻塞,这时其实也是RUNNING。
代码实践
我们可以通过代码来查看上面图中出现的6种状态:
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TestClass {
public static void main(String[] args) {
// NEW
Thread t1 = new Thread("t1") {
@Override
public void run() {
log.debug("running...");
}
};
// RUNNABLE
Thread t2 = new Thread("t2") {
@Override
public void run() {
while (true) {
}
}
};
t2.start();
// TERMINATED
Thread t3 = new Thread("t3") {
@Override
public void run() {
// log.debug("running...");
}
};
t3.start();
// TIMED_WAITING
Thread t4 = new Thread("t4") {
@Override
public void run() {
synchronized (TestClass.class) {
try {
sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t4.start();
// WAITING
Thread t5 = new Thread("t5") {
@Override
public void run() {
try {
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t5.start();
// BLOCKED
Thread t6 = new Thread("t6") {
@Override
public void run() {
synchronized (TestClass.class) {
try {
sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t6.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.debug("t1 state {}", t1.getState());
log.debug("t2 state {}", t2.getState());
log.debug("t3 state {}", t3.getState());
log.debug("t4 state {}", t4.getState());
log.debug("t5 state {}", t5.getState());
log.debug("t6 state {}", t6.getState());
Thread thread = new Thread(() -> {
});
}
}
查看控制台:
12:53:59.304 [main] DEBUG com.grq.threadState.TestClass - t1 state NEW
12:53:59.309 [main] DEBUG com.grq.threadState.TestClass - t2 state RUNNABLE
12:53:59.309 [main] DEBUG com.grq.threadState.TestClass - t3 state TERMINATED
12:53:59.309 [main] DEBUG com.grq.threadState.TestClass - t4 state TIMED_WAITING
12:53:59.309 [main] DEBUG com.grq.threadState.TestClass - t5 state WAITING
12:53:59.309 [main] DEBUG com.grq.threadState.TestClass - t6 state BLOCKED
标签:状态,生命周期,Java,Thread,WAITING,TestClass,state,线程
From: https://blog.csdn.net/qq_52127701/article/details/142095921