线程的状态是一个枚举类型 Thread.state
- public static void main(String[] args) {
- for (Thread.State state : Thread.State.values()) {
- System.out.println(state);
- }
- }
下面我详细解释一下这几种状态的含义:


从上图来看, 最开始是一个 NEW 状态, 然后进入 RUNNABLE 状态, 也就是线程开始运行了, 再然后运行完了就进入 TERMINATED 状态, 这是主干道, 线程从开始到结束的状态, 然后再 RUNNABLE 过程中可能会产生其他状态, 就是 TIMED_WAITING 和 BLOCKED 和 WAITING, RUNNABLE 可以在这三个状态之间转换, 怎样进入 WAITING 状态呢, 也就是 wait方法和join()不带参数的版本, 要是进入 TIMED_WAITING 状态呢, 就是sleep和join(time)带时间的版本, 而进入 BLOCKED 呢就是加锁 synchronized ,这是整体的状态转换.
下面我们通过代码看一下状态的变化:
- public static void main(String[] args) {
- Thread thread = new Thread( () -> {
- for (int i = 0; i < 1000_000; i++) {
- // 在这个循环里什么也不干
- }
- });
-
- // 此时 thread 得到的就是 NEW
- System.out.println(thread.getState());
-
- thread.start();
-
- try {
- thread.join();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- // thread 结束之后, 得到的状态就是 TERMINATED
- System.out.println(thread.getState());
- }

而在 start 和 join() 之间获取状态的话, 就是 RUNNABLE.


而我们要是在运行中的时候用上 sleep 和 join(time) 带时间的版本, 得到的状态就是 TIME_WAITING.
- public static void main(String[] args) throws InterruptedException {
- Thread thread = new Thread( () -> {
- // for (int i = 0; i < 100_000_000; i++) {
- // // 在这个循环里什么也不干
- // }
-
- try {
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- });
-
- // 此时 thread 得到的就是 NEW
- System.out.println(thread.getState());
-
- thread.start();
-
- Thread.sleep(50);
- //thread.join(10000);
-
- // thread 正在运行中, 此时得到的状态就是 RUNNABLE
- System.out.println(thread.getState());
-
- try {
- thread.join();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- // thread 结束之后, 得到的状态就是 TERMINATED
- System.out.println(thread.getState());
- }

运行的时候, 遇到 sleep , 得到的状态就是 TIMED_WAITING, 没有的话就是 RUNNABLE 状态.
下面来看一下 BLOCKED 和 RUNNABLE 的转换:
处于 BLOCKED 状态的线程是因为在等待锁的释放。假如有两个线程 t1 和 t2,t1 线程提前获得了锁并且暂未释放锁,此时 t2 就处于 BLOCKED 状态。
- public static void main(String[] args) {
- Thread t1 = new Thread(new Runnable() {
- @Override
- public void run() {
- test();
- }
- }, "t1");
-
- Thread t2 = new Thread(new Runnable() {
- @Override
- public void run() {
- test();
- }
- }, "t2");
-
- t1.start();
- t2.start();
-
- System.out.println(t1.getName() + ":" + t1.getState());
- System.out.println(t2.getName() + ":" + t2.getState());
- }
-
- // 争夺锁
- private static synchronized void test() {
- try {
- Thread.sleep(2000L);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }

从打印结果我们就可以看出来, t1 线程因为先于 t2 线程获得锁并且还在未释放的状态下, t1 线程处于 RUNNABLE 状态下, t2 线程处于 BLOCKED 状态下.
而当我们让 main 线程休眠1000毫秒的话, 此时线程状态转换就是:
