目录

  • 线程生命周期的五个阶段
  • 1. 新建线程:New
  • 2. 线程就绪:Runnble
  • 3. 线程处于运行状态:Running
  • 4. 线程阻塞:Blocked
  • 5.死亡状态:Dead



上一篇文章写了Java线程的创建方式,本篇文章讨论一下Java中线程的生命周期。

线程生命周期的五个阶段

总的来说,Java的生命周期分为以下几个阶段:

  1. 新建
  2. 就绪
  3. 运行
  4. 阻塞
  5. 死亡

流程图如下:

java线程runnable java线程的生命周期_多线程

下面分别进行讨论

1. 新建线程:New

在上一篇文章里,已经写到了线程创建的几种方式,它们的本质其实都是new出一个Thread对象,然后调用底层操作系统的相关接口,实现一个和操作系统线程相对应的线程对象。这时系统会为这个线程分配内存并且初始化一些成员变量,此时线程就是处于一个新建的状态下。

2. 线程就绪:Runnble

新建线程之后,操作系统也分配了相应的资源,但是该线程并没有处于运行的状态,甚至连获得CPU的资格都没有。这时候,还是需要调用线程的start方法,如果是线程池的话,就需要调用execute方法或者submit方法来让线程进入就绪状态。此时,JVM完成了方法调用栈和程序计数器的创建,等待线程的调度和运行。

3. 线程处于运行状态:Running

运行状态是指线程获得了CPU的使用权,当线程获得CPU使用权之后,线程就会执行run方法中编写的逻辑。

4. 线程阻塞:Blocked

线程阻塞是指线程主动或者被动地获得了CPU的使用权进入暂停的状态。在这个时候,线程是中止的,需要再次竞争到CPU的使用权才可以转变为运行状态。
发生阻塞时有三种状态:

  1. 等待阻塞:如调用对象的wait方法时,JVM就会将线程放到等待队列中,线程就处于阻塞状态。
  2. 同步阻塞:运行时的线程想要获取被其他线程已经占用的同步锁时,线程就转为了阻塞状态。此时,JVM将线程存入了锁池(Lock pool)中。
  3. 其他阻塞:调用Thread的sleep方法、join方法或者发生I/O请求时候,JVM也会把线程转为阻塞状态。当达到sleep时间、join状态终止或者超时,I/O完毕时,线程才会重新转变为运行状态。

5.死亡状态:Dead

以下情况下线程就转换为了死亡状态:

  1. 线程运行完毕:线程执行了run方法中的所有逻辑,线程就转换为了死亡状态。
  2. 线程发生异常退出:在线程处于运行状态时,当线程发生无法处理的Error或者未被catch的Exception的时候,线程就会退出。
  3. 强制退出:当线程对象调用stop方法来强制结束线程时候,线程就会进入死亡状态。但是这种方式是瞬间释放线程占用的同步锁,可能会导致线程发生死锁的现象,所以这种方式并不是一种很好的方式,尽量不用。