图解: 线程状态转换(线程生命周期这一篇够用了)

线程生命周期

结尾有彩蛋

多线程常见面试问题

  1. 调用new方法创建线程时,线程就创建了吗?
  2. 调用start方法后,线程就被执行了吗?
  3. 线程是能从BLOCKED状态直接进入RUNNING状态吗?
  4. 线程可以从TERMINATED状态转换为其他状态吗?

线程生命周期状态转化图

图解: 线程状态转换(线程生命周期这一篇够用了)_第1张图片

根据线程的生命周期,可以分为5个状态,但是如果从编程角度分析:有另一个版本的线程状态分类

  1. NEW(创建状态)
  2. RUNNABLE(可执行状态)
  3. RUNNING(执行状态)
  4. BLOCKED(阻塞状态)
  5. TERMINATED(死亡状态)

NEW(创建)状态

当使用new关键字创建一个线程对象时,此时线程并不是可执行状态,因为这时候还没有调用start方法,这个时候的线程处于NEW状态。

此时线程是不存在的,对,这个时候应该说只是创建了一个线程对象,并没有创建线程(第一个问题答案)。

NEW状态的线程只可以通过start方法进入RUNNABLE状态,只能进入RUNNABLE状态,不能进入RUNNING状态(实际上RUNNING状态可以看成一种特殊的RUNNABLE状态)。

RUNNABLE(可执行)状态

通过调用start方法线程对象进入RUNNABLE状态,这个时候JVM才会正在的去创建线程,但是此时线程没有被立即执行,或者说不能被立即执行(第二个问题答案)。线程是否被执行取决于能否得到CPU的调度,
也是由于这个原因,线程无法从new状态直接进入RUNNING状态,即便得到调度的时间很短。

另外,RUNNABLE状态的线程是不能直接进入BLOCKED状态的。
排除意外终止的情况,RUNNABLE状态的线程只能进入RUNNING状态。原因很简单,即便我们调用了waitsleep或者其他的线程操作,这些操作也必须得到CPU调度才能生效,一旦线程得到CPU调度,线程的状态也就从RUNNABLE转换为了RUNNING

RUNNING(执行)状态

一旦CPU从任务的可执行队列里选中了线程,线程这时候就转换为了RUNNING状态,也是这时候才开始执行自己的逻辑代码(包括wait,sleep等方法)。

RUNNING状态的线程可以发生如下几种情况的转换:

  1. 主动进入BLOCKED状态,例如:通过调用sleep或者wait方法,线程被加入到waitSet中。
  2. 被动进入BLOCKED状态,例如:获取锁资源,或者遇到阻塞IO操作等
  3. 进入TERMINATED状态,例如:调用了stop方法(该方法已经不推荐使用)或者意外中断。
  4. 主动进入RUNNABLE状态,调用yield方法放弃CPU的执行权。
  5. 被动进入RUNNABLE状态,CPU调度器放弃了该线程的执行权。

这个队列就是ThreadGroup,它非常重要

说到这个waitSet,上面说如果按照编程角度来看,还有其他的一种为线程分类的方式,而在waitSet中的线程在那种分类方式中叫Timed Waiting(限期等待)

BLOCKED(阻塞)状态

上面已经阐述了线程如何进入BLOCKED状态,接下来就聊一下线程可以从BLOCKED状态切换到哪些状态:

  1. 进入TERMINATED状态,例如:调用了stop方法(该方法已经不推荐使用)或者意外中断(例如:JVM Crash导致所有线程结束)。
  2. 线程阻塞操作结束,进入RUNABLE状态。
  3. 线程休眠结束,进入RUNNABLE状态
  4. wait 中的线程被其他线程调用notifynotifyall唤醒,进入RUNNABLE状态
  5. 线程得到锁资源,进入RUNNABLE状态。
  6. 其他线程调用了interrupt方法,线程进入RUNNABLE状态

线程是不能从BLOCKED状态直接进入RUNNING状态的。(问题3)

TERMINATED(终止)状态

先回答一下上面第四个的问题,线程是不能从TERMINATED状态转换为其他状态的。TERMINATED是线程的最终状态,线程进入该状态意味着线程的整个生命周期结束。

彩蛋

图解: 线程状态转换(线程生命周期这一篇够用了)_第2张图片
超神学院语录

我心存彦,吾彦永恒

留下一个问题:

Thread中的start和run方法是什么关系?

你可能感兴趣的:(#,多线程与高并发,多线程,java,线程的生命周期,线程状态)