Java线程的生命周期

105 阅读3分钟
  • 线程的生命周期

一个完整的线程生命周期,要经过 新建(new)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)5种状态。


new阶段

new阶段就是你new Thread()创建线程对象时候的阶段。

new阶段下其实线程根本还是不存在的,我们只是创建了一个Therad对象,就和我们最常用的new关键字是一个道理。

只有当我们真正把线程启动起来的时候,此时才会在JVM进程中把我们的线程创建出来。

我们new了一个Thread对象之后就需要调用Thread.start()来启动线程,此时线程会从new阶段转换到Runnable阶段。

 Runnable阶段

只有调用Thread.start()方法才能使线程从new阶段转换到Runnable阶段。

当然我们从字面意思也可以知道此时线程是处于可执行转状态而不是真正的执行中状态了,此时的线程只能等CPU翻牌子,翻到了他才能真正的跑起来。

有些同学可能会说要是CPU一直不翻牌子咋办?严格意义上来讲,处在Runnable的线程只有两条出路,一条是线程意外退出,还有一条是被CPU翻牌子进入Running阶段。

3.Running阶段

有了解过这块内容的同学看到这里可能会有疑问,java线程状态中并没有这个状态,为什么我们在讲生命周期的时候会把这一状态单独拆分出来做讲解?为了章节内容的流畅性,这块内容的解释放到下一节去讲解,这边我们还是继续讲我们的线程生命周期。

好的我们继续

这个阶段的线程已经获取到了CPU调度执行权,也就是说处于运行中状态了。

在该阶段中,线程可以向前或者向后发生转换:

  • 由于CPU的调度器轮询导致该线程放弃执行,就会进入Runnable阶段。

  • 线程主动调用yield,放弃CPU执行权,就会进入Runnable阶段(这种方式并不是百分百生效的,在CPU资源不紧张的时候不会生效)。

  • 调用sleep、wait方法,进入Blocked阶段(这里讲的Blocked阶段和线程的Blocked状态需要区分开,这边讲的是一个比较广义的Blocked的阶段)

  • 进行某个阻塞的IO操作而进入Blocked阶段

  • 为了获取某个锁资源而加入到该锁到阻塞队列中而进入Blocked阶段

  • 线程执行完成或者调用stop方法或者判断某个逻辑标识,直接进入Terminated阶段

Blocked阶段

进入该阶段的原因已经在Running阶段阐述过了,这里就不再说明,这里主要介绍一下处于该阶段的线程可以如何切换。

  • 直接进入Terminated,比如调用stop方法或者意外死亡(JVM Crash

  • 线程阻塞的操作结束,读取或者写入了想操作的数据进入Runnable状态

  • 线程完成了指定时间的休眠,进入Runnable状态

  • Wait状态的线程被notify或者notifyall唤醒,进入Runnable状态

  • 获取到了锁资源,进入Runnable状态

  • 线程阻塞过程被打断,比如调用interrupt方法,进入Runnable状态

Terminated状态

Terminated状态是一个线程的最终状态,在该状态中线程不会切换到其他任何状态。

线程进入Terminated状态意味着线程整个生命周期结束了,进入Terminated状态的方式有以下三种

  • 线程正常结束

  • 线程意外结束

  • JVM Crash