Windows线程状态

windows线程状态.jpg
Windows系统中,线程可以初于上图中7中状态之一:

  • 初始态
    线程在创建过程中处于初始态,创建完成后,此线程被放入就绪队列。
  • 就绪态
    线程已经获得除CPU以外所有资源,处于等待调度执行的状态。内核的调度程序维护所有就绪线程队列,并按照优先级次序进行调度。
  • 准备态
    已选中在特定处理器上运行的下一个线程,此线程处于准备态并等待线程描述表切换。如果准备态的线程优先级足够高,可以从运行线程那里抢占处理器,否则将等待直至运行线程进入等待态或时间片用完。系统中的每个处理器上只能有一个处于准备态的线程。
  • 运行态
    内核执行线程切换,准备态线程进入运行态并开始执行,直至它被抢占、或用完时间片、或阻塞、或终止时为止。在前两种情况下,线程就转换为就绪态。
  • 等待态
    线程进入等待态的原因有:出现阻塞事件;等待同步信号;环境子系统要求线程挂起。等待事件条件满足且所有资源可用时,线程就转换为就绪态。
  • 过渡态
    线程完成等待后准备运行,但此时资源不可用,线程就转换为过渡态。例如,线程的内核堆栈被调出主存,当资源可用时(内核堆栈被调入主存),过渡态线程进入就绪态。
  • 终止态
    线程可以被自己或其他线程终止,此时线程进入终止态。一旦结束工作完成后,线程就可以从系统中移去。如果执行体有一个指向线程对象的指针,可将处于终止态的线程对象重新初始化并再次使用。

Linux线程状态

Linux进程状态.png

  • 运行状态(TASK_RUNNING)
    指正在被CPU运行或者就绪的状态。这样的进程被成为runnning进程。运行态的进程可以分为3种情况:内核运行态、用户运行态、就绪态。
  • 可中断睡眠状态(TASK_INTERRUPTIBLE)
    处于等待状态中的进程,一旦被该进程等待的资源被释放,那么该进程就会进入运行状态。
  • 不可中断睡眠状态(TASK_UNINTERRUPTIBLE)
    该状态的进程只能用wake_up()函数唤醒。
  • 暂停状态(TASK_STOPPED)
    当进程收到信号SIGSTOP、SIGTSTP、SIGTTIN或SIGTTOU时就会进入暂停状态。可向其发送SIGCONT信号让进程转换到可运行状态。
  • 僵死状态(TASK_ZOMBIE)
    当进程已经终止运行,但是父进程还没有询问其状态的情况。
  • 页面被对换出主存的进程所处的状态(TASK_SWAPPING)

####Java线程状态
JAVA线程状态.jpg

线程共包括以下5种状态。

  • 新建状态(New)
    线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。
  • 就绪状态(Runnable)
    也被称为“可执行状态”。线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行。
  • 运行状态(Running)
    线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。
  • 阻塞状态(Blocked)
    阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
    1. 等待阻塞
      通过调用线程的wait()方法,让线程等待某工作的完成。
    2. 同步阻塞
      线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。
    3. 其他阻塞
      通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
  • 死亡状态(Dead)
    线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

Java线程状态与操作系统线程的联系

Java中的线程是JVM模拟操作系统得来的,JVM中的线程状态,不反应任何操作系统线程状态。Java多线程是在JVM中实现的,而JVM相对于操作系统是一个进程。我们用Java编写的多线程程序对于OS来说是不可见的。