Java并发基础-线程状态及转换

每个线程都有状态,表示当前的线程是否在运行或者是等待某些事情的发生等。
本文先对线程的几个状态进行解释,然后再说明线程如何在这几个状态之间跳转。

本文目录:

1 基础知识

操作系统在实际运行过程中,可能有很多个线程一直同时在运行。相对单个CPU来说,同一时间运行的线程数只能有一个。但如果所有线程都排队等待上一线程处理完毕后再执行下一线程,会带来很多问题,如一些非关键的线程长期占用CPU,而导致某些关键线程等待时间很长等;在这种情况下,操作系统一般对CPU的使用按线程进行分配,限定每个线程的连续执行时间;也就是说,每个线程在执行一段时间后,必须释放CPU,所有线程一起按某些规则竞争CPU的下次分片使用时间。

2 状态说明

线程有以下几个状态:

  • NEW
    新建状态,线程创建后直到调用其start方法前都属于这个状态。
  • RUNNABLE
    就绪状态,线程可以被执行,但未获取到操作系统的某些资源(如第一节中所说的CPU时间分片)而导致未执行;
  • RUNNING
    运行状态,线程正在被执行
  • BLOCKED
    阻塞状态,线程被阻塞从而未运行,需要等待唤醒事件的发生
  • DEAD
    死亡状态,线程执行完毕

3 线程状态转换

线程在上述几个状态之间可以相互转换,其状态转换图如下所示:
这里写图片描述

3.1 新建->就绪

当线程调用start方法时,从新建(NEW)状态过度到就绪(RUNNABLE)状态;

3.2 就绪->运行

当线程在就绪状态时,如果获取到了足够的操作系统资源(如CPU等),它将会从就绪状态进入到运行状态;
这个过程是由操作系统进行调度的,开发人员不能也无需处理这种状态的转换。

3.3 运行->就绪

当线程在运行过程中,当前所分配的操作系统资源(如CPU时间片等)使用完毕,则会由运行状态转换到就绪状态。
此过程也是由操作系统调度控制,开发人员一般无需关注。除非某些场景下CPU等操作系统资源不够导致线程执行时间变长时,可以考虑对操作系统的某项受限资源进行扩展以提高效率。
开发人员也可以通过Thread.yeild方法放弃当前的资源,此时操作系统将重新选择线程执行,当前线程的状态也会从运行转换成 就绪;但也有可能操作系统立即选择了刚放弃的线程再次执行。

3.4 运行->阻塞

线程运行过程中,如果遇到以下事件将会进入阻塞状态:

  • 调用wait方法
  • 调用Thread.join方法
  • 调用Thread.sleep方法
  • 调用某个Condition的await方法
  • 调用锁的lock类方法
  • 其它

3.5 阻塞->就绪

线程在阻塞状态时,根据其阻塞的原因,如果遇到对应的某些事件发生,则会由阻塞状态进入就绪状态。
如它阻塞的原因是调用锁的lock方法,那么在获取到锁时将会进入就绪状态。

3.6 运行->死亡

当线程执行完毕时,会由运行状态跳转到死亡状态。

猜你喜欢

转载自blog.csdn.net/icarusliu/article/details/79548902
今日推荐