Thread对象的生命周期及状态间转换

线程的状态详解

Question:run方法何时被调用?

调用start方法后并不会立即执行run方法,而是等待CPU选中本线程后才会被调用。如果由于某种原因,本线程在CPU的竞争中无法被选中,那么start之后run方法一直也不会被调用。

一、NEW状态

当一个Thread对象刚刚被创建时,状态为NEW。此状态仅仅表示Thread对象被创建出来了,但此时Thread对象和其他java对象没有区别,仅仅是存在于内存之中。当Thread对象调用start方法后,它的状态改变为Runnable,此时Thread对象进入到CPU的竞争对列中。

状态转换:
NEW——>Runnable:Thread对象调用了start方法。

二、RUNNABLE状态

Thread对象进入Runnable状态只有一种情况,那就是Thread对象调用了Start方法后变为Runnable状态。但是此时Thread对象还不能执行任务,因为此时Thread对象还在等待CPU的调用。Runnable的含义就是Thread对象可以执行了,不过还未执行,此时在等待CPU的调度。

状态转换:
1、Runnable——>Running:当等到CPU调度时,状态变为Running。
2、Runnable——>Terminated:在等待CPU调度期间,如果被意外终止,那么则会直接进入Terminated状态。

三、RUNNING状态

Runnable状态的线程,一旦被CPU选中执行,它就会变为Running状态。此时才会真正运行run方法逻辑。处于Running状态的线程,其实也同时是Runnable状态。

其中,Blocked状态的线程通过resume或者notify/nofifyAll先重新进入Runnable状态,等待CPU调度后再进入Running状态。

状态转换:
1、Running——>Blocked:

  • Running的线程如果在执行过程中调用了wait或者sleep方法,就会进入Blocked状态
  • 阻塞的IO操作
  • 进入到锁的阻塞队列

2、Running——>Terminated:

  • run方法正常执行结束。
  • 运行意外中止
  • 调用stop方法

3、Running——>Runnable:

  • CPU轮转,放弃该线程的执行
  • 调用了Thread的yield方法,提示CPU可以让出自己的执行权。如果CPU对此响应,则会进入到Runnable状态,而不是Terminated。

四、BLOCKED状态

只有Running状态的线程才会进入Blocked状态,进入Blocked状态的原因在Running状态转换的时候已经说过了。

状态转换:
1、Blocked——>Runnable状态:

  • 阻塞操作结束了,那么线程将切换回Runnable状态。注意不是Running状态,此时线程需要等待CPU的再一次选中。
  • 阻塞过程被打断了,由于其他线程调用了interrupt方法,也会回到Runnable状态
  • 线程休眠的时间结束了,也会回到Runnable状态
  • 由于wait操作进入Blocked状态的线程,其他线程发出了notify或notifyAll,则会唤醒它,回到Runnable状态
  • 由于等待锁而被Blocked的线程。一旦获取了锁,那么便会回到Runnable状态。

2、Blocked——>Terminated状态:

  • 线程Blocked状态时,有可能由于调用了stop或者意外终止,而直接进入了Terminated状态。

五、TERMINATED状态

Terminated状态意外着线程的生命周期已经走完。这是线程的终止状态。此状态的线程不会再转化为其他任何状态。

处于Running或者Blocked状态的线程都有可能变为Terminated状态,但原因是类似的,如下:

  • 线程运行正常结束
  • 程序运行异常终止
  • JVM意外终止

相关文章: