多线程出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());
相关推荐
像污秽一样5 分钟前
软件开发新技术复习
java·spring boot·后端·rabbitmq·cloud
浮游本尊10 分钟前
Java学习第7天 - 网络编程与数据库操作
java
武昌库里写JAVA11 分钟前
关于springcloud的坑
java·开发语言·spring boot·学习·课程设计
西猫雷婶20 分钟前
python学智能算法(十四)|机器学习朴素贝叶斯方法进阶-CountVectorizer文本处理简单测试
人工智能·python·机器学习
yihuiComeOn32 分钟前
【大数据高并发核心场景实战】 - 数据持久化之冷热分离
java·后端
Zephyrtoria36 分钟前
动态规划:01 背包(闫氏DP分析法)
java·算法·动态规划
范纹杉想快点毕业39 分钟前
解析Qt文件保存功能实现
java·开发语言·c++·算法·命令模式
你不困我困40 分钟前
啊啊啊啊啊啊啊啊code
java
电商API_180079052471 小时前
API 接口:程序世界的通用语言与交互基因
爬虫·python·数据挖掘·网络爬虫