Java的每个线程都具有自己的状态,Thread类中成员变量threadStatus存储了线程的状态:

private volatile int threadStatus = 0;

在Thread类中也定义了状态的枚举,共六种,如下:

public enum State {NEW,          //  新建状态RUNNABLE,       //  执行状态BLOCKED,        //  阻塞状态WAITING,        //  无限期等待状态TIMED_WAITING,  //  有限期等待状态TERMINATED;     //  退出状态
}

threadStatus初始值为0,对应的就是NEW状态。

  • NEW:新建状态,new Thread()时处于这个状态,此时线程还未开始执行
  • RUNNABLE:执行状态,当调用了start方法后,线程处于此状态,当然此刻CPU不一定正在执行它
  • BLOCKED:阻塞状态,线程等待锁时处于此状态
  • WAITING:无限期等待状态,需要被唤醒的等待属于此状态,如Object.wait
  • TIMED_WAITING:有限期等待状态,调用一些有超时时间的等待方法会进入此状态,如Thread.sleep、Object.wait、Thread.join、Lock.tryLock、Condition.await
  • TERMINATED:退出状态,可能是正常运行完毕,也可能是抛出了异常导致线程终止

我们可以通过getState获取线程的状态:

State state = thread.getState();

接下来,我们通过示例来感受线程状态的变化。

示例一:

Thread t = new Thread(() -> {System.out.println("sleep");//    休眠2秒ThreadUtil.sleep(2000);System.out.println("run");
});//   启动前先打印一下线程状态
System.out.println(t.getState());
//  启动线程
t.start();
//  启动后立即打印一次线程状态
System.out.println(t.getState());// 每隔500毫秒打印一次线程状态
while (true) {ThreadUtil.sleep(500);System.out.println(t.getState());
}

输出:

NEW
RUNNABLE
sleep
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
run
TERMINATED
TERMINATED
TERMINATED
TERMINATED
TERMINATED
TERMINATED
TERMINATED

可以看出,线程创建后,初始状态为NEW;
调用start方法后状态变更为了RUNNABLE;
当线程内执行了sleep,休眠2秒钟,状态变更为了TIMED_WAITING;
当线程执行完成后,状态变更为了TERMINATED。

示例二:
本示例演示在多线程争抢锁的情况下,线程状态的变化。

private static Object lock = new Object();public static void main(String[] args) {Runnable runnable = () -> {// 加锁synchronized (lock) {System.out.println(Thread.currentThread().getName() + " lock");ThreadUtil.sleep(2000);}System.out.println(Thread.currentThread().getName() + " exit");};Thread t1 = new Thread(runnable, "t1");Thread t2 = new Thread(runnable, "t2");t1.start();t2.start();while (true) {ThreadUtil.sleep(500);System.out.println(t1.getName() + ":" + t1.getState());System.out.println(t2.getName() + ":" + t2.getState());}
}

输出:

t1 lock              t1获得了锁
t1:TIMED_WAITING    t1 sleep,进入有限等待状态
t2:BLOCKED          t2未获得锁,因此进入阻塞状态
t1:TIMED_WAITING
t2:BLOCKED
t1:TIMED_WAITING
t2:BLOCKED
t1 exit             t1释放锁,执行完成,退出
t2 lock             t2获得锁
t1:TERMINATED       t1已经是退出状态
t2:TIMED_WAITING    t2 sleep,进入有限等待状态
t1:TERMINATED
t2:TIMED_WAITING
t1:TERMINATED
t2:TIMED_WAITING
t1:TERMINATED
t2:TIMED_WAITING
t2 exit            t2释放锁,执行完成,退出
t1:TERMINATED      t1为退出状态
t2:TERMINATED      t2为退出状态

示例三:
本示例演示了线程如何进入和退出WAITING状态。

private static Object obj = new Object();public static void main(String[] args) {Runnable runnable = () -> {synchronized (obj) {try {// 等待obj.wait();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("exit");}};Thread t1 = new Thread(runnable, "t1");System.out.println(t1.getName() + ":" + t1.getState());t1.start();System.out.println(t1.getName() + ":" + t1.getState());for (int i = 0; i < 20; i++) {ThreadUtil.sleep(500);if(i == 3) {synchronized (obj) {//   唤醒obj.notify();}}System.out.println(t1.getName() + ":" + t1.getState());}
}

输出:

t1:NEW
t1:RUNNABLE
t1:WAITING  调用了obj.wait()进入无限等待状态
t1:WAITING
t1:WAITING
t1:BLOCKED  主线程获得锁,进行notify,t1进入了阻塞状态
exit               t1线程退出同步块,执行完成
t1:TERMINATED  t1线程退出
t1:TERMINATED

Java Thread的threadStatus字段值的更新代码位于hotspot c++源码中,JDK源码中看不到。
Java的线程状态并非是操作系统的实际线程状态,但与操作系统的线程状态是有对应关系的,后续有需要深入分析操作系统原理、hotspot源码再展开。

Java线程状态详解相关推荐

  1. Java 线程池详解及实例代码

    转载自  Java 线程池详解及实例代码 这篇文章主要介绍了Java 线程池的相关资料,并符实例代码,帮助大家学习参考,需要的朋友可以参考下 线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时 ...

  2. jstack 线程状态详解

    jstack 线程状态详解 jatsck 用法 线程状态 一图以庇之 系统线程状态 (Native Thread Status) jatsck 用法 #jstack -h Usage:jstack [ ...

  3. Java线程池详解学习:ThreadPoolExecutor

    Java线程池详解学习:ThreadPoolExecutor Java的源码下载参考这篇文章:Java源码下载和阅读(JDK1.8) - zhangpeterx的博客 在源码的目录java/util/ ...

  4. Java 线程池详解学习:FixedThreadPool,CachedThreadPool,ScheduledThreadPool...

    Java常用的线程池有FixedThreadPool和CachedThreadPool,我们可以通过查看他们的源码来进行学习. Java的源码下载参考这篇文章:Java源码下载和阅读(JDK1.8) ...

  5. java线程池详解及五种线程池方法详解

    基础知识 Executors创建线程池 Java中创建线程池很简单,只需要调用Executors中相应的便捷方法即可,比如Executors.newFixedThreadPool(int nThrea ...

  6. 一文详解java线程池 详解Java线程池的七个参数 详解池化技术 java如何选择核心线程数 详解Java线程池的拒绝策略

    目录 引言 线程池使用场景 加快请求响应(响应时间优先) 加快处理大任务(吞吐量优先) 特殊说明 线程池的池化技术 线程池的创建 手动创建 创建newFixedThreadPool线程池 创建newS ...

  7. Java线程属性详解(Demo-Java基础)

    你好我是辰兮,很高兴你能来阅读,本篇文章继续为大家讲解Java多线程之线程属性,下面有案例的截图和相关代码可以自行实践,相关的更多面试知识已经提前整理好文章可以阅读学习,分享获取新知,希望对Java初 ...

  8. Java 线程池详解

    构造一个线程池为什么需要几个参数?如果避免线程池出现OOM?Runnable和Callable的区别是什么?本文将对这些问题一一解答,同时还将给出使用线程池的常见场景和代码片段. 基础知识 Execu ...

  9. 【转载】Java线程池详解

    目录 1.线程池的优势 2.Java中的ThreadPoolExecutor类 3.线程池的主要参数 4.线程池流程 5.线程池为什么需要使用(阻塞)队列? 6.线程池为什么要使用阻塞队列而不使用非阻 ...

最新文章

  1. java point_java中point是什么意思
  2. 查询删除的外向交货单
  3. 程序员养发(老师付推荐)
  4. Spring Boot功能实战
  5. 解决gvim中php函数提示php_funclist.dict无法生效的问题
  6. C语言求斐波那契数列前10项
  7. iOS 创建推送证书
  8. Sphinx安装与基本设置
  9. 多元Huffman编码问题
  10. python文本分类评价指标 top1如何计算_推荐算法评价指标
  11. Windows 10 开启卓越性能模式
  12. 状态模式,懂你的另一半
  13. 你认为996是一种荣耀吗?
  14. C语言 推箱子游戏 地图编辑器(简单)
  15. matlab画增益频率,HFSS中如何查看增益随频率的变化曲线?
  16. 基于ATMEGA16单片机,MQ-3酒精传感器,LCD1602液晶显示的酒精浓度检测阈值报警仪
  17. Canvas 画九宫格图片
  18. Mt7628调试简记
  19. 【笔记】html 图片映射 usemap(vue环境下、map、area、coords)
  20. C语言C++图形库---贪吃蛇大作战【附源码】

热门文章

  1. 手机屏幕尺寸、分辨率,图像像素、分辨率、实际大小解惑
  2. vue 可用的 ui_ui设计的10种可用性启发法
  3. 动态规划之背包问题 01背包
  4. 5*5盒式滤波器matlab代码
  5. 激活信息管理slmgr.vbs命令详解
  6. [Delphi] 多线程编程
  7. python中columns是什么意思_Python Pandas DataFrame.columns用法及代码示例
  8. Python的wheel文件安装
  9. 三部操作实现 ubuntu安装图像化桌面
  10. 安装Dev c++后,编译文件出现未编译的解决方法