当前位置: 首页 > news >正文

多线程——线程状态

目录

1.线程的状态

1.1 NEW

1.2 RUNNABLE

1.3 BLOCKED

1.4 WAITING

1.5 TIMED_WAITING

1.6 TERMINATED

2.线程状态的相互转换


在上期的学习中,已经理解线程的启动(start())、休眠(sleep())、中断(interrupt())和等待(join())等核心概念。通过这些操作,线程会在不同的状态之间切换。那么,线程在这些过程中究竟经历了哪些状态?它们是如何转换的?这是本期要探讨的问题。

在前面谈到进程状态时,主要讲了就绪状态和阻塞状态,这是两个经典的状态。在线程中,线程的状态有六种,分别是:NEWRUNNABLEBLOCKEDWAITINGTIMED_WAITINGTERMINATED。这几个状态在 Java 中属于枚举类型,可以用代码实现查看这些状态:

public class Demo14 {public static void main(String[] args) {for (Thread.State state : Thread.State.values()) {System.out.println(state);}}
}

下面将对它们一 一介绍。

1.线程的状态

1.1 NEW

小帅对自己的女神小美仰慕已久,小帅同学打算好好打扮自己去追求女神小美,但是小帅心里胆怯,所以到目前为止,只是停留在仰慕的状态。此时小帅心里有追求女神小美的想法,但还没开始行动 start(),属于 NEW 状态。

NEW:是指一个线程已经被创建(new),但是还没开始执行的状态,称新建状态,也就是这个时候还没用调用 start()

public class Demo14 {public static void main(String[] args) {Thread thread = new Thread(() -> {//.........},"小帅");System.out.println(thread.getName() + ":" + thread.getState());//thread.start();//这里已经注释,没有调用start()}
}

运行结果:

1.2 RUNNABLE

终于,小帅下定决心,开启了对小美的追求之路。每天会和女神聊聊天,偶尔会约女神吃饭,也会给女神送礼物。此时小帅已经有实际行动了 start(),女神小美可能会立即回复,也有可能在忙其他事情,属于 RUNNABLE 状态。

RUNNABLE是指线程正在 JVM 中正在执行或者准备执行的状态,成可运行状态。也就是线程已经创建,并且调用了 start() 方法,新建线程开始执行。

public class Demo14 {public static void main(String[] args) {Thread thread = new Thread(() -> {},"小帅");System.out.println("调用start()前:" + thread.getName() + ":" + thread.getState());thread.start();System.out.println("调用start()后:" + thread.getName() + ":" + thread.getState());}
}

运行结果:

1.3 BLOCKED

小帅追求一段时间后,小美也对他有所回应,于是小帅想约小美周末一起看个电影,但是小美说你约晚了,周末要和好闺蜜一起去逛街。此时小帅不能约到小美,因为小美被闺蜜占用了,属于BLOCKED 状态。

BLOCKED:是指线程处于阻塞状态。这个是由于锁导致的,在下期线程安全问题会有讲解,这里先做一个了解。

public class Demo14 {public static void main(String[] args) throws InterruptedException {Object locker = new Object();Thread thread1 = new Thread(() -> {synchronized (locker){while (true) {System.out.println("闺蜜和小美在逛街....");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}},"闺蜜");Thread thread2 = new Thread(() -> {synchronized (locker){System.out.println("小帅约小美看电影....");}},"小帅");thread1.start();thread2.start();}
}

这里需要借助 jconsole 查看状态,关于 jconsole 在前面的文章《多线程——认识Thread类和创建线程》有讲。状态如下:

可以看到,“小帅”这个线程的状态就是 BLOCKED。

1.4 WAITING

时间来到第二周,虽然上周小帅没有约到小美一起看电影,但是啊,小帅没有放弃,于是小帅再次鼓气勇气再约女神一次,这次女神说这周末目前没有安排,但是这周工作有点忙,具体要看后面的时间安排,于是说“等我有时间联系你把”,但是小美并没有说会多久联系。于是呢,小帅觉得有点希望的,所以就一直等啊等,不分白天黑夜的一直在等女神的消息。此时,小帅一直等,没有期限的等待就属于 WAITING 状态。

WAITING是指某线程无限期等待其他线程执行特定任务的状态,称等待状态。也就是说需要其他线程完成一定的任务后,这个状态才能进行,需要调用 join() 方法。

public class Demo14 {public static void main(String[] args) throws InterruptedException {Thread thread1 = new Thread(() -> {while (true) {try {System.out.println("等待小美联系中....");Thread.currentThread().join();} catch (InterruptedException e) {throw new RuntimeException(e);}}},"小帅");Thread thread2 = new Thread(() -> {System.out.println("回复了小帅的邀约....");},"小美");thread1.start();thread1.join();thread2.start();}
}

借助 jconsole 查看状态,状态如下:

1.5 TIMED_WAITING

如果上面例子中,如果小美对小帅说“我这周比较忙,不一定有时间,我两三天内再回复你能不能出去看电影吧。”此时,小帅就会等小美的回复,但不会一直等下去了,最多就等三天,此时的等待就属于 TIMED_WAITING。

TIMED_WAITING是指线程在指定的时间内等待,这个等待有期限,称计时等待状态

public class Demo14 {public static void main(String[] args) throws InterruptedException {Object locker = new Object();Thread thread1 = new Thread(() -> {while (true) {System.out.println("等待小美联系中....");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}},"小帅");Thread thread2 = new Thread(() -> {System.out.println("回复了小帅的邀约....");},"小美");thread1.start();thread1.join(5000);//这里设置等待5秒thread2.start();}
}

借助 jconsole 查看状态,状态如下:

1.6 TERMINATED

小帅和小美在联系一段时间后,小帅和小美决定彼此并不合适,所以并没有在一起,小帅也放弃了追求小美,至此小帅对仰慕已久的女神的追求彻底结束了,属于 TERMINATED 状态。

TERMINATED是指线程执行完毕的状态,称终止状态。

public class Demo14 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(()->{//....},"小帅");thread.start();thread.join();System.out.println(thread.getName() + "对女神的追求结束了... 现在的状态是:" + thread.getState());}
}

运行结果:

2.线程状态的相互转换

虽然线程状态的相互转换看似复杂,但主要是理解各个状态的含义以及是怎么发生的,这对于在后续的多线程学习中是非常重要的,尤其是调试程序找 bug 的时候,想要在多线程程序中进行调试,理解线程的状态是非常重要的,并且还需会使用 jconsole 或者其他根据查看当前线程的状态,比如前文使用 jconsole 查看状态时,还可以看到一些其他信息比如当前的状态是发生在哪一行。在这张转换图里,看到了一些方法比如 wait(),这个也是等待的方法,用法和 join() 类似,但在这里不深入讲解,在后面会专门写一期 wait() 的用法,以及 synchronized() { } 等都会详细解析介绍到。


本期主要介绍多线程的线程状态,主要过程状态是NEW -> RUNNABLE -> TERMINATED,然后在这个过程中发生一些状态转换,主要理解每个状态的含义并可以借助一些工具如  jconsole 查看线程状态。

从多线程的创建学习到现在,我们也理解了多线程的优势,但是那多线程一定很安全吗?是不是多线程可以随意使用呢?在 Java 基础学习中,我们谈到 StringBuffer 和 StringBuilder 时,说 StringBuffer 是线程安全的,而 StringBuilder 是线程不安全的。可见线程会存在安全问题,为什么会有线程安全问题以及导致线程安全问题的原因是什么?

欲知后事如何,且听下回分解!

http://www.xdnf.cn/news/1457839.html

相关文章:

  • 并发编程——17 CPU缓存架构详解高性能内存队列Disruptor实战
  • ResNet(残差网络)-彻底改变深度神经网络的训练方式
  • linux——自定义协议
  • 多Agent协作案例:用AutoGen实现“写代码+测Bug”的自动开发流程
  • 秒店功能更新:多维度优化升级,助力商家经营
  • 当 LLM 遇上真实世界:MCP-Universe 如何撕开大模型 “工具能力” 的伪装?
  • 记录相机触发相关
  • 机器学习入门,第一个MCP示例
  • (D题|矿井突水水流漫延模型与逃生方案)2025年高教杯全国大学生数学建模国赛解题思路|完整代码论文集合
  • 生成式引擎优化(GEO):数字营销新标配,企业如何抢占AI搜索流量高地?
  • Trae + MCP : 一键生成专业封面的高阶玩法——自定义插件、微服务编排与性能调优
  • 设计模式六大原则2-里氏替换原则
  • Linux —— 环境变量
  • mysql中find_in_set()函数的使用, ancestors字段,树形查询
  • AI视频画质提升效果实用指南:提升清晰度的完整路径
  • [论文阅读] 软件工程 | REST API模糊测试的“标准化革命”——WFC与WFD如何破解行业三大痛点
  • 【论文阅读】-《Besting the Black-Box: Barrier Zones for Adversarial Example Defense》
  • AutoLayout与Masonry:简化iOS布局
  • (E题|AI 辅助智能体测)2025年高教杯全国大学生数学建模国赛解题思路|完整代码论文集合
  • 解密llama.cpp:Prompt Processing如何实现高效推理?
  • Nginx 实战系列(一)—— Web 核心概念、HTTP/HTTPS协议 与 Nginx 安装
  • Scikit-learn Python机器学习 - 特征预处理 - 归一化 (Normalization):MinMaxScaler
  • 孩子学手机里的坏毛病,怎样限制他打开某些APP?
  • Flutter 3.35.2 以上版本中 数字转字符串的方法指南
  • 机器学习基础-day05-深度学习框架PyTorch的tensor及PyTorch进行线性回归
  • 猫头虎AI 荐研|腾讯开源长篇叙事音频生成模型 AudioStory:统一模型,让 AI 会讲故事
  • 数据结构 之 【哈希的相关概念】
  • npm/pnpm软链接的优点和使用场景
  • 2025精选榜:4款好用的企业即时通讯软件推荐!安全有保障
  • 【Proteus仿真】AT89C51单片机中断系列仿真——INT0中断控制LED小灯/INT0和INT1中断控制数码管