设为首页 加入收藏

TOP

面试官:Java 线程有哪几种状态?它们之间是怎么切换的?(一)
2023-08-26 21:11:00 】 浏览:72
Tags:Java 程有哪

来源:https://blog.csdn.net/limenghua9112/article/details/106975105

为何要了解Java线程状态

线程是 JVM 执行任务的最小单元,理解线程的状态转换是理解后续多线程问题的基础。

Java线程状态转换图

Java线程有哪些状态?

在 JVM 运行中,线程一共有 NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED 六种状态,这些状态对应 Thread.State 枚举类中的状态。

推荐一个开源免费的 Spring Boot 实战项目:

https://github.com/javastacks/spring-boot-best-practice

Thread.State枚举源码:

为方便阅读,在此去掉了文档注释

public enum State {
 NEW,
 RUNNABLE,
 BLOCKED,
 WAITING,
 TIMED_WAITING,
 TERMINATED;
}

在给定的时间点,线程只能处于这些状态中的一种状态。这些状态是不反映任何操作系统线程状态的虚拟机状态。

NEW,TERMINATED

这两个状态比较好理解,当创建一个线程后,还没有调用start()方法时,线程处在 NEW 状态,线程完成执行,退出后变为TERMINATED终止状态。

RUNNABLE

运行 Thread 的 start 方法后,线程进入 RUNNABLE 可运行状态

/**
 * 程序目的:观察线程的各种状态
 * created at 2020-06-26 19:09
 * @author lerry
 */
class MyThread extends Thread {
 @Override
 public void run() {
  System.out.printf("%s线程运行\n", Thread.currentThread().getName());
 }
}

/**
 * 分别观察创建线程后、start()后、和线程退出后的线程状态。
 * 其中Thread.sleep(50);是为了等待线程执行完
 */
public class ThreadStateDemo {
 public static void main(String[] args) throws InterruptedException {
  MyThread myThread = new MyThread();
  System.out.printf("创建线程后,线程的状态为:%s\n", myThread.getState());
  myThread.start();
  System.out.printf("调用start()方法后线程的状态为:%s\n", myThread.getState());
  // 休眠50毫秒,等待MyThread线程执行完
  Thread.sleep(50);
  System.out.printf("再次打印线程的状态为:%s\n", myThread.getState());

 }
}

输出结果:

创建线程后,线程的状态为:NEW
调用start()方法后线程的状态为:RUNNABLE
Thread-0线程运行
再次打印线程的状态为:TERMINATED

我们可以看到,输出结果符合预期。

  • 在刚创建完线程后,状态为NEW
  • 调用了start()方法后线程的状态变为:RUNNABLE。
  • 然后,我们看到了run()方法的执行,这个执行,是在主线程main打印了调用start()方法后线程的状态为:RUNNABLE输出后执行的。
  • 随后,我们让main线程休眠了50毫秒,等待MyThread线程退出
  • 最后再打印MyThread线程的状态,为TERMINATED。

BLOCKED

如图左侧所示,在运行态中的线程进入 synchronized 同步块或者同步方法时,如果获取锁失败,则会进入到 BLOCKED 状态。当获取到锁后,会从 BLOCKED 状态恢复到就绪状态。

import lombok.extern.slf4j.Slf4j;

/**
 * 程序目的:观察线程的BLOCKED状态
 * created at 2020-06-26 19:09
 * @author lerry
 */
@Slf4j
public class ThreadBlockedStateDemo {

 public static void main(String[] args) {
  Thread threadA = new Thread(() -> method01(), "A-Thread");
  Thread threadB = new Thread(() -> method01(), "B-Thread");

  threadA.start();
  threadB.start();

  log.info("线程A的状态为:{}", threadA.getState());
  log.info("线程B的状态为:{}", threadB.getState());
 }

 /**
  * 停顿10毫秒、模拟方法执行耗时
  */
 public static synchronized void method01() {
  log.info("[{}]:开始执行主线程的方法", Thread.currentThread().getName());
  try {
   Thread.sleep(10);
  }
  catch (InterruptedException e) {
   e.printStackTrace();
  }
  log.info("[{}]:主线程的方法执行完毕", Thread.currentThread().getName());
 }
}

输出结果:

2020-06-26 20:32:15.404 [A-Thread] INFO  com.hua.threadtest.state.ThreadBlockedStateDemo - [A-Thread]:开始执行主线程的方法
2020-06-26 20:32:15.404 [main    ] INFO  com.hua.threadtest.state.ThreadBlockedStateDemo - 线程A的状态为:RUNNABLE
2020-06-26 20:32:15.407 [main    ] INFO  com.hua.threadtest.state.ThreadBlockedStateDemo - 线程B的状态为:BLOCKED
2020-06-26 20:32:15.417 [A-Thread] INFO  com.hua.threadtest.state.ThreadBlockedStateDemo - [A-Thread]:主线程的方法执行完毕
2020-06-26 20:32:15.418 [B-Thread] INFO  com.hua.threadtest.state.ThreadBlockedStateDemo - [B-Thread]:开始执行主线程的方法
2020-06-26 20:32:15.430 [B-Thread] INFO  com.hua.thread
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇SpringBoot 下一篇SpringBoot3集成Kafka

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目