【JMM】线程之状态(Windows+Linux+Java)
Windows线程状态
Windows系统中,线程可以初于上图中7中状态之一:
- 初始态
线程在创建过程中处于初始态,创建完成后,此线程被放入就绪队列。 - 就绪态
线程已经获得除CPU以外所有资源,处于等待调度执行的状态。内核的调度程序维护所有就绪线程队列,并按照优先级次序进行调度。 - 准备态
已选中在特定处理器上运行的下一个线程,此线程处于准备态并等待线程描述表切换。如果准备态的线程优先级足够高,可以从运行线程那里抢占处理器,否则将等待直至运行线程进入等待态或时间片用完。系统中的每个处理器上只能有一个处于准备态的线程。 - 运行态
内核执行线程切换,准备态线程进入运行态并开始执行,直至它被抢占、或用完时间片、或阻塞、或终止时为止。在前两种情况下,线程就转换为就绪态。 - 等待态
线程进入等待态的原因有:出现阻塞事件;等待同步信号;环境子系统要求线程挂起。等待事件条件满足且所有资源可用时,线程就转换为就绪态。 - 过渡态
线程完成等待后准备运行,但此时资源不可用,线程就转换为过渡态。例如,线程的内核堆栈被调出主存,当资源可用时(内核堆栈被调入主存),过渡态线程进入就绪态。 - 终止态
线程可以被自己或其他线程终止,此时线程进入终止态。一旦结束工作完成后,线程就可以从系统中移去。如果执行体有一个指向线程对象的指针,可将处于终止态的线程对象重新初始化并再次使用。
Linux线程状态
- 运行状态(TASK_RUNNING)
指正在被CPU运行或者就绪的状态。这样的进程被成为runnning进程。运行态的进程可以分为3种情况:内核运行态、用户运行态、就绪态。 - 可中断睡眠状态(TASK_INTERRUPTIBLE)
处于等待状态中的进程,一旦被该进程等待的资源被释放,那么该进程就会进入运行状态。 - 不可中断睡眠状态(TASK_UNINTERRUPTIBLE)
该状态的进程只能用wake_up()函数唤醒。 - 暂停状态(TASK_STOPPED)
当进程收到信号SIGSTOP、SIGTSTP、SIGTTIN或SIGTTOU时就会进入暂停状态。可向其发送SIGCONT信号让进程转换到可运行状态。 - 僵死状态(TASK_ZOMBIE)
当进程已经终止运行,但是父进程还没有询问其状态的情况。 - 页面被对换出主存的进程所处的状态(TASK_SWAPPING)
####Java线程状态
线程共包括以下5种状态。
- 新建状态(New)
线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。 - 就绪状态(Runnable)
也被称为“可执行状态”。线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行。 - 运行状态(Running)
线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。 - 阻塞状态(Blocked)
阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:- 等待阻塞
通过调用线程的wait()方法,让线程等待某工作的完成。 - 同步阻塞
线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。 - 其他阻塞
通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
- 等待阻塞
- 死亡状态(Dead)
线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
Java线程状态与操作系统线程的联系
Java中的线程是JVM模拟操作系统得来的,JVM中的线程状态,不反应任何操作系统线程状态。Java多线程是在JVM中实现的,而JVM相对于操作系统是一个进程。我们用Java编写的多线程程序对于OS来说是不可见的。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ClawHub的技术分享!