Java线程状态详解
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线程状态详解相关推荐
- Java 线程池详解及实例代码
转载自 Java 线程池详解及实例代码 这篇文章主要介绍了Java 线程池的相关资料,并符实例代码,帮助大家学习参考,需要的朋友可以参考下 线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时 ...
- jstack 线程状态详解
jstack 线程状态详解 jatsck 用法 线程状态 一图以庇之 系统线程状态 (Native Thread Status) jatsck 用法 #jstack -h Usage:jstack [ ...
- Java线程池详解学习:ThreadPoolExecutor
Java线程池详解学习:ThreadPoolExecutor Java的源码下载参考这篇文章:Java源码下载和阅读(JDK1.8) - zhangpeterx的博客 在源码的目录java/util/ ...
- Java 线程池详解学习:FixedThreadPool,CachedThreadPool,ScheduledThreadPool...
Java常用的线程池有FixedThreadPool和CachedThreadPool,我们可以通过查看他们的源码来进行学习. Java的源码下载参考这篇文章:Java源码下载和阅读(JDK1.8) ...
- java线程池详解及五种线程池方法详解
基础知识 Executors创建线程池 Java中创建线程池很简单,只需要调用Executors中相应的便捷方法即可,比如Executors.newFixedThreadPool(int nThrea ...
- 一文详解java线程池 详解Java线程池的七个参数 详解池化技术 java如何选择核心线程数 详解Java线程池的拒绝策略
目录 引言 线程池使用场景 加快请求响应(响应时间优先) 加快处理大任务(吞吐量优先) 特殊说明 线程池的池化技术 线程池的创建 手动创建 创建newFixedThreadPool线程池 创建newS ...
- Java线程属性详解(Demo-Java基础)
你好我是辰兮,很高兴你能来阅读,本篇文章继续为大家讲解Java多线程之线程属性,下面有案例的截图和相关代码可以自行实践,相关的更多面试知识已经提前整理好文章可以阅读学习,分享获取新知,希望对Java初 ...
- Java 线程池详解
构造一个线程池为什么需要几个参数?如果避免线程池出现OOM?Runnable和Callable的区别是什么?本文将对这些问题一一解答,同时还将给出使用线程池的常见场景和代码片段. 基础知识 Execu ...
- 【转载】Java线程池详解
目录 1.线程池的优势 2.Java中的ThreadPoolExecutor类 3.线程池的主要参数 4.线程池流程 5.线程池为什么需要使用(阻塞)队列? 6.线程池为什么要使用阻塞队列而不使用非阻 ...
最新文章
- java point_java中point是什么意思
- 查询删除的外向交货单
- 程序员养发(老师付推荐)
- Spring Boot功能实战
- 解决gvim中php函数提示php_funclist.dict无法生效的问题
- C语言求斐波那契数列前10项
- iOS 创建推送证书
- Sphinx安装与基本设置
- 多元Huffman编码问题
- python文本分类评价指标 top1如何计算_推荐算法评价指标
- Windows 10 开启卓越性能模式
- 状态模式,懂你的另一半
- 你认为996是一种荣耀吗?
- C语言 推箱子游戏 地图编辑器(简单)
- matlab画增益频率,HFSS中如何查看增益随频率的变化曲线?
- 基于ATMEGA16单片机,MQ-3酒精传感器,LCD1602液晶显示的酒精浓度检测阈值报警仪
- Canvas 画九宫格图片
- Mt7628调试简记
- 【笔记】html 图片映射 usemap(vue环境下、map、area、coords)
- C语言C++图形库---贪吃蛇大作战【附源码】