java高并发总结3--java线程的生命周期

我们都知道每一个线程都有自己的局部变量、程序计数器,以及生命周期等,这边博客主要介绍线程的生命周期。

在介绍线程的生命周期之前,先思考一个问题:执行了Thread的start方法就代表线程已经开始执行了吗?
在这里插入图片描述
通过上图的展示可知,线程的生命周期大体可以分为如下5个主要阶段:

  1. new
  2. runnable
  3. running
  4. blocked
  5. terminal

1、线程的new状态
当我们用new关键字创建一个thread对象时,此时它并不处于执行状态,因为没有调用start方法启动该线程,那么线程的状态为new状态,准确的说,它只是一个thrad对象状态,因为没有start之前,该线程根本不不存在,与你用关键字new创建一个普通的java对象没什么区别。
new状态通过start方法进入runnable状态。
2、线程的runnable状态
线程对象进入runnable状态必须调用start方法,那么此时才是真正地在JVM进程中创建了一个线程,线程一经创建就可以立即得到执行吗?答案是否定的,线程的运营与否与进程一样都要听令于CPU的调度,那么我们把这个中间状态称之为可执行状态(runnable),也就说它具备执行的资格,但是并没有真正的执行起来而是在等待CPU的调度。
由于存在running状态,所以不会直接进入blocked状态和terminated状态,即使是在线程的执行逻辑中调用wait,sleep或者其他blocked的IO操作等,也必须先获得CPU的调度执行权才可以,严格来讲,runnable的线程只能意外种植或者进入running状态。

3、线程的running状态
一旦cpu通过轮询或者其他方式从任务可执行队列中选中了线程,那么此时它才能真正的执行自己的逻辑代码,需要说明的一点是一个正在running状态的线程事实上也是runnable的,但是反过来则不成立。
在该状态中,线程的状态可以发生如下状态转换。

  1. 直接进入terminated状态,比如调用JDK已经部推荐使用的STOP方法或者判断某个逻辑标识。
  2. 进入blocked状态,比如调用了sleep,或则wait方法而加入了waitSet中。
  3. 进行某个阻塞的IO操作,比如因网络数据的读写而进入了Blocked状态。
  4. 获取某个锁资源,从而加入到该锁阻塞队列中而进入了Blocked状态。
  5. 由于CPU的调度器轮询使该线程放弃执行,进入runnable状态。
  6. 线程主动调用yield方法,放弃CPU执行权,进入runnable状态。

4、线程的blocked状态
上面已经介绍了如何进入blocked状态,此处就不才赘述。线程在blocked状态中可以切换至以下几个状态。

  1. 直接进入terminated状态,比如调用JDK已经部推荐使用的stop方法或者意外死亡(JVM crash)。
  2. 线程阻塞的操作结束,比如读取了想要的数据字节进入到runnable状态。
  3. 线程完成了制定时间的休眠,进入到了runnable状态。
  4. wait中的线程被其他线程notify/notifyAll唤醒,进入runnable状态。
  5. 线程获取到了某个锁资源,进入runnable状态。
  6. 线程在阻塞过程中被打断,比如其他线程调用interupt方法,进入runnable状态。

5、线程的terminated状态
terminated是一个线程的最终状态,在改状态中线程将不会切换到其他任何状态,线程进入terminated状态,意味着该线程的整个生命周期都结束了,下面这些情况将会使terminated状态。

  1. 线程运行正常结束,结束生命周期。
  2. 线程运行出错意外结束。
  3. JVM crash,导致所有的线程都结束。

猜你喜欢

转载自blog.csdn.net/ppwwp/article/details/86695135
今日推荐