专栏首页Java架构筑基Java 多线程之线程的生命周期 | 图解
原创

Java 多线程之线程的生命周期 | 图解

←←←←←←←←←←←← 快!点关注

在 Java 初中级面试中,关于线程的生命周期可以说是常客了。本文就针对这个问题,通过图文并茂的方式详细说说。

结合上图,线程的生命周期大致可分为以下五种状态:

  • NEW - 新建
  • RUNNABLE - 等待被CPU调度
  • RUNNING - 正在运行
  • BLOCKED - 阻塞
  • TERMINATED - 结束

一、NEW 状态

NEW 状态表示线程被新建的状态,我们来看一段示例代码:

Thread thread = new Thread(() -> System.out.println("Hello, world !"));

很多人以为当我们在代码中new一个Thread的时候,就代表着thread线程处于NEW状态了,实际上是大错大错的!

实际上,只有当我们调用线程start()方法之后,该线程才会被创建出来,而不是通过new关键字来创建的,new关键字仅仅是创建了一个普通的 Java 对象而已。

NEW 状态的线程能发生哪些状态转变

NEW 状态的线程在调用start()方法后,进入 RUNNABLE 状态。

二、RUNNABLE 状态

当我们在代码中显式的调用start()方法后,JVM 进程会去创建一个新的线程,而此线程不会马上被 CPU 调度运行,进入 RUNNING 状态,这里会有一个中间状态,就是 RUNNABLE 状态,你可以理解为等待被 CPU 调度的状态:

如上图所示,也就是说被创建的出来的线程会从NEW -> RUNNABLE状态,等待 CPU 调度,再大白话一点,就是说这种线程具备被执行的资格,但是能否进入进行阶段,还得看 CPU 的脸色说话。

RUNNABLE 状态的线程能发生哪些状态转变

RUNNABLE 状态的线程无法直接进入 BLOCKED 状态和 TERMINATED 状态的。

很多小伙伴这里可能有疑问,为啥呢

只有处在 RUNNING 状态的线程,换句话说,只有获得 CPU 调度执行权的线程才有资格进入 BLOCKED 状态和 TERMINATED 状态

PS: RUNNABLE 状态的线程要么能被转换成 RUNNING 状态,要么被意外终止(如 kill -9 PID)。

三、RUNNING 状态

当 CPU 调度发生,并任务队列中选中了某个 RUNNABLE 线程时,该线程会进入 RUNNING 执行状态,并且开始调用run()方法中逻辑代码。

RUNNING 状态的线程能发生哪些状态转变

  • 被转换成 TERMINATED 状态,比如调用 stop() 方法;
  • 被转换成 BLOCKED 状态,比如调用了sleep, wait 方法被加入 waitSet 中;
  • 被转换成 BLOCKED 状态,如进行 IO 阻塞操作,如查询数据库进入阻塞状态;
  • 被转换成 BLOCKED 状态,比如获取某个锁的释放,而被加入该锁的阻塞队列中;
  • 该线程的时间片用完,CPU 再次调度,进入 RUNNABLE 状态;
  • 线程主动调用 yield 方法,让出 CPU 资源,进入 RUNNABLE 状态;

四、BLOCKED 状态

上小节中我们已经讲到了,进入 BLOCKED 原因,这里,我们就直接谈谈 BLOCK 状态的线程能够发生哪些状态改变:

  • 被转换成 TERMINATED 状态,比如调用 stop() 方法,或者是 JVM 意外 Crash;
  • 被转换成 RUNNABLE 状态,阻塞时间结束,比如读取到了数据库的数据后;
  • 完成了指定时间的休眠,进入到 RUNNABLE 状态;
  • 正在 wait 中的线程,被其他线程调用 notify/notifyAll 方法唤醒,进入到 RUNNABLE 状态;
  • 线程获取到了想要的锁资源,进入 RUNNABLE 状态;
  • 线程在阻塞状态下被打断,如其他线程调用了 interrupt 方法,进入到 RUNNABLE 状态;

五、TERMINATED 状态

TERMINATED 状态是线程的最终状态,处于此状态中的线程不会切换到以上任何状态,一旦线程进入了 TERMINATED 状态,就意味着这个线程生命的终结,没有回头路了。

以下情况下,线程会进入到 TERMINATED 状态:

  • 线程正常运行结束,生命周期结束;
  • 线程运行过程中出现意外错误;
  • JVM 异常结束,所有的线程生命周期均被结束。

六、start 方法源码解析,何时调用的 run() 方法?

通过图文,我们了解了线程生命周期的五种状态,接下来,我们来看看 start 方法源码,其实内部的源码非常简单,如下图所示:

  • ①:首先,会判断线程的状态是否是 NEW 状态,内部对应的状态标识是个 0,也就是说如果不等于 0,直接抛线程状态异常;
  • ②:线程在启动后被加入到 ThreadGroup 中;
  • ③: start0 是最核心的方法了,就是运行状态为 NEW (内部状态标识为 0) 的线程;
  • ④:start0 是个 native 方法,也就是 JNI 方法; 看到这里,你也许会有个疑问,自己重写的 run 方法是什么时候被调用的呢?源码中也没看到调用啊!!

Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.

上面这段截自 JDK 官方文档,意思是说:

run 方法是在调用 JNI 方法 start0() 的时候被调用的,被调用后,我们写的逻辑代码才得以被执行

一些面试中,面试官也会经常问到这个问题:线程的 start 方法和 run 方法有什么区别?

相信看完上面的源码分析,小伙伴们一定可以源码的角度怼回去了!

七、总结

本文中,通过图文的方式解释了线程的五种状态,以及各种状态能够被转换的状态。最后,我们简单看了一下 start()内部源码,知道了 run() 方法何时被执行的。

读者福利:

分享免费学习资料

针对于Java程序员,我这边准备免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)

为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!希望读到这的您能点个小赞和关注下我,以后还会更新技术干货,谢谢您的支持!

资料领取方式:加入Java技术交流群963944895点击加入群聊,私信管理员即可免费领取

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 如何扩展和优化线程池?

    多线程的软件设计方法确实可以最大限度的发挥现代多核处理器的计算能力,提高生产系统的吞吐量和性能。但是,如果一个系统同时创建大量线程,线程间频繁的切换上下文导致的...

    本人秃顶程序员
  • Java面试 32个核心必考点完全解析

    1~3年内从工程师到高级工程师发展,夯实基础,重点提高工作基础能力,培养技术的深度和广度,对不同方向的新技术保持强烈的好奇心和学习心

    本人秃顶程序员
  • 一文讲解重量级锁、自旋锁、轻量级锁、偏向锁、悲观、乐观锁等各种锁

    重量级锁?自旋锁?自适应自旋锁?轻量级锁?偏向锁?悲观锁?乐观锁?执行一个方法咋这么辛苦,到处都是锁。

    本人秃顶程序员
  • 经典面试题-线程状态

    cwl_java
  • Java线程池深度揭秘

    Executor 是一个接口(主要用于定义规范),定义了 execute 方法,用于接收 Runnable 对象。

    一猿小讲
  • 一年经验Java开发0713面试

    MongoDB单个文档的存储限制是16M,如果要存储大于16M的文件,就要用到MongoDB GridFS。

    三分恶
  • Java并发编程:线程的基本状态

    一、线程的基本状态 线程基本上有5种状态,分别是:NEW、Runnable、Running、Blocked、Dead。 1)新建状态(New) 当线程对象对创建...

    陈树义
  • 多线程基础(一): 线程概念及生命周期

    什么是进程,相信大家都知道什么是进程却很难解释清楚。百科中的解释是:进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调...

    冬天里的懒猫
  • 并发编程之第三篇(synchronized)

    重量级锁竞争的时候,还可以使用自旋来进行优化,如果当前线程自旋成功(即这时候持锁线程已经退出了同步块,释放了锁),这时当前线程就可以避免阻塞。 自旋重试成功的...

    海仔
  • 「BAT面试」搞懂并发编程,轻松应对80%的面试场景

    作为一个合格的Java程序员,必须要对并发编程有一个深层次的了解,在很多互联网企业都会重点考察这一块。可能很多工作3年以上的Java程序员对于这一领域几乎没有太...

    美的让人心动

扫码关注云+社区

领取腾讯云代金券