多线程出bug不知道如何调试?java线程几种常见状态

当你的多线程代码结构很复杂的时候很难找出bug的原因所在,此时我们可以使用getState()方法获取该线程当前的状态,通过观察其状态是阻塞了还是因为没有启动等原因导致的。

状态 描述
NEW 安排了工作,还未开始行动
RUNNABLE 可工作的,又可以分成正在工作中和即将开始工作
BLOCKED 这几个都表示排队等着其他事情
WAITING 这几个都表示排队等着其他事情
TIMED_WAITING 这几个都表示排队等着其他事情
TERMINATED 工作完成了

NEW

此状态说明这个线程已经被创建了,但是没有start()执行任务。

java 复制代码
   Thread t = new Thread(() -> {
       for (int i = 0; i < 1000_0000; i++) {
       }
   }, "状态");
   System.out.println(t.getName() + ": " + t.getState());

RUNNABLE

这个状态表明他已经被创建,但是还没有执行完任务,在这个过程中都是RUNNABLE状态。

java 复制代码
   Thread t = new Thread(() -> {
       for (int i = 0; i < 1000_0000; i++) {
       }
   }, "状态");
   t.start();
   while (t.isAlive()) {
       System.out.println(t.getName() + ": " + t.getState());
   }

TERMINATED

已经执行完任务了,是线程结束的标志

java 复制代码
 Thread t = new Thread(() -> {
     for (int i = 0; i < 1000_0000; i++) {
     }
 }, "状态");
t.start();
t.join();
System.out.println(t.getName() + ": " + t.getState());

WAITING

当他在使用wait,join,sleep方法等待的时候,并且方法没有传入参数,也就是死等的时候,需外部唤醒(如 notify()),处于此状态。

java 复制代码
  Thread t1 = Thread.currentThread();
  Thread t = new Thread(() -> {
      try {
          t1.join();
      } catch (InterruptedException e) {
          throw new RuntimeException(e);
      }
  }, "状态");
  t.start();
  Thread.sleep(10);
  System.out.println(t.getState());

TIMED_WAITING

当他在使用wait,join,sleep方法等待的时候,并且传入参数会进入此状态,超时后自动唤醒或外部提前唤醒,和WAITING的区别就是是否传入参数的区别。

java 复制代码
  Thread t1 = Thread.currentThread();
  Thread t = new Thread(() -> {
      try {
          Thread.sleep(1000);
      } catch (InterruptedException e) {
          throw new RuntimeException(e);
      }
  }, "状态");
  t.start();
  Thread.sleep(10);
  System.out.println(t.getState());

BLOCKED

因为锁竞争导致的等待时,会进入此状态,如果一直是此状态可能是陷入了死锁。

java 复制代码
//这个案例是个死锁。
  Object locker1 = new Object();
  Object locker2 = new Object();
  Thread t1 = new Thread(()->{
      synchronized (locker1) {
          try {
              Thread.sleep(1);
          } catch (InterruptedException e) {
              throw new RuntimeException(e);
          }
          synchronized (locker2) {
          }
      }
      System.out.println("t1执行完毕");
  });

  Thread t2 = new Thread(()->{
      synchronized (locker2) {
          synchronized (locker1) {
          }
      }
      System.out.println("t2执行完毕");
  });
  t1.start();
  t2.start();
  Thread.sleep(100);
  System.out.println(t1.getState());
相关推荐
mit6.82420 分钟前
[nanoGPT] ChatGPT 的 LLM 的全栈实现 | 快速上手
python
DKunYu26 分钟前
2.1线性回归
pytorch·python·深度学习·1024程序员节
大飞记Python28 分钟前
实战分享:一键自动化下载指定版本的Chrome及Chromedriver(附Python源码)
chrome·python·自动化
eguid_11 小时前
【开源项目分享】JNSM1.2.0,支持批量管理的jar包安装成Windows服务可视化工具,基于Java实现的支持批量管理已经安装服务的可视化工具
java·开源·jar·1024程序员节·windows服务·jar包安装成服务·exe安装成服务
杯莫停丶1 小时前
设计模式之:享元模式
java·设计模式·享元模式
遥远_2 小时前
Java微服务无损发布生产案例
java·spring·微服务·优雅停机·java微服务无损发布
苹果醋32 小时前
学习札记-Java8系列-1-Java8新特性简介&为什么要学习Java8
java·运维·spring boot·mysql·nginx
程序员杰哥2 小时前
如何使用Postman做接口自动化测试及完美的可视化报告?
自动化测试·软件测试·python·测试工具·jenkins·postman·1024程序员节
武子康2 小时前
Java-159 MongoDB 副本集容器化 10 分钟速查卡|keyfile + –auth + 幂等 init 附 docker-compose
java·数据库·mongodb·docker·性能优化·nosql·1024程序员节
m0_748233642 小时前
C++ 模板初阶:从函数重载到泛型编程的优雅过渡
java·c++·算法·1024程序员节