操作系统层面描述

从操作系统层面来说,线程的状态分为5种,如下图所示:
image.png

  • 【初始状态】仅是在语言层面创建了线程对象,还未与操作系统线程关联
  • 【可运行状态】(就绪状态)指该线程已经被创建(与操作系统线程关联),可以由 CPU 调度执行 ,但还未被 CPU 调度执行
  • 【运行状态】指获取了 CPU 时间片运行中的状态,已经被 CPU 调度执行了。当 CPU 时间片用完,会从运行状态转换至可运行状态,会导致线程的上下文切换
  • 【阻塞状态】如果调用了阻塞 API,如 BIO 读写文件,这时该线程实际不会用到 CPU,会导致线程上下文切换,进入阻塞状态。等 BIO 操作完毕,会由操作系统唤醒阻塞的线程,转换至可运行状态。与可运行状态的区别是,对阻塞状态的线程来说只要它们一直不唤醒,调度器就一直不会考虑调度它们
  • 【终止状态】表示线程已经执行完毕,生命周期已经结束,不会再转换为其它状态,即线程已经死亡

    Java语言层面描述

    状态介绍

    image.png

  • 【NEW】实现Runnable接口和继承Thread可以得到一个线程类,new一个实例出来,线程就进入了初始状态,但是还没有调用 start 方法。

  • 【RUNNABLE】Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
  • 【BLOCKED】表示线程阻塞于锁,是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态。
  • 【WAITING】进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断),处于这种状态的线程不会被分配CPU执行时间,它们要等待被显式地唤醒,否则会处于无限期等待的状态。
  • 【TIME_WAITING】该状态不同于WAITING,它可以在指定的时间后自行返回,处于这种状态的线程不会被分配CPU执行时间,不过无须无限期等待被其他线程显示地唤醒,在达到一定时间后它们会自动唤醒。
  • 【TERMINATED】表示该线程已经执行完毕,在一个终止的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。处于该状态的线程对象也许是活的,但是它已经不是一个单独执行的线程,线程一旦终止就不能复生。

image.png

  1. @Slf4j(topic = "c.ThreadState")
  2. public class ThreadState {
  3. public static void main(String[] args) {
  4. //NEW - new了线程对象,但是没有调用start方法
  5. Thread t1 = new Thread(() -> {
  6. log.debug("running...");
  7. },"t1");
  8. //RUNNABLE - 线程正在run中(分为 RUNNING 和 READY)
  9. Thread t2 = new Thread(() -> {
  10. while (true) {
  11. }
  12. },"t2");
  13. t2.start();
  14. //TERMINATED - t3线程运行完run方法后就进入终止状态了
  15. Thread t3 = new Thread(() -> {
  16. log.debug("running...");
  17. },"t3");
  18. t3.start();
  19. //TIMED_WAITING - t4线程调用了Thread.sleep(1000000),处于超时等待
  20. Thread t4=new Thread(()->{
  21. synchronized (ThreadState.class){
  22. try {
  23. Thread.sleep(1000000);
  24. } catch (InterruptedException e) {
  25. e.printStackTrace();
  26. }
  27. }
  28. },"t4");
  29. t4.start();
  30. //WAITING - t5线程等待t2线程的执行完毕,而t2线程永远无法自动执行完,所以处于永久等待
  31. Thread t5=new Thread(()->{
  32. try {
  33. t2.join();
  34. } catch (InterruptedException e) {
  35. e.printStackTrace();
  36. }
  37. },"t5");
  38. t5.start();
  39. //BLOCKED - ThreadState.class的对象锁被t4线程占有,因此t6处于阻塞状态
  40. Thread t6=new Thread(()->{
  41. synchronized (ThreadState.class){
  42. try {
  43. Thread.sleep(1000000);
  44. } catch (InterruptedException e) {
  45. e.printStackTrace();
  46. }
  47. }
  48. },"t6");
  49. t6.start();
  50. log.debug("t1 state {}" + t1.getState());
  51. log.debug("t2 state {}" + t2.getState());
  52. log.debug("t3 state {}" + t3.getState());
  53. log.debug("t4 state {}" + t4.getState());
  54. log.debug("t5 state {}" + t5.getState());
  55. log.debug("t6 state {}" + t6.getState());
  56. }
  57. }

image.png

状态转化

状态转化图如下所示:
image.png
具体情况如下图所示:
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png