【线程】线程的生命周期和状态

秒速五厘米 2024-03-17 09:23 196阅读 0赞

(1)从OS层面,5状态模型

在这里插入图片描述

  • 【初始状态】仅是在语言层面创建了线程对象,还未与操作系统线程进行关联

    • 相当于我们new Thread(),线程对象已经有了,但是还没有调用其start()
  • 【可运行状态】(就绪状态)指该线程已经被创建(与操作系统线程关联),随时可以由 CPU 调度执行

    • 调用线程的start()方法,此线程进入就绪状态。
    • 当前线程sleep()方法结束,其他线程join()结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入就绪状态。
    • 当前线程时间片用完了,调用当前线程的yield()方法,当前线程进入就绪状态。
    • 锁池里的线程拿到对象锁后,进入就绪状态。
  • 【运行状态】指获取了 CPU 时间片运行中的状态

    • 当 CPU 时间片用完,会从【运行状态】转换至【可运行状态】,会导致线程的上下文切换
  • 【阻塞状态】

    • 如果调用了阻塞 API,如 BIO 读写文件,这时该线程实际不会用到 CPU,会导致线程上下文切换,进入 【阻塞状态】
    • 等 BIO 操作完毕,会由操作系统唤醒阻塞的线程,转换至【可运行状态】
    • 与【可运行状态】的区别是,对【阻塞状态】的线程来说只要它们一直不唤醒,调度器就一直不会考虑 调度它们
    • 阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态。
  • 【终止状态】表示线程已经执行完毕,生命周期已经结束,不会再转换为其它状态

(2)从 Java API 层面来描述的,根据 Thread.State 枚举,分为六种状态

在这里插入图片描述

  • NEW 新建状态,线程对象刚被创建,但是还没有调用 start() 方法
  • RUNNABLE 当调用了 start() 方法之后,就会进入Runnable状态。

    • 注意,Java API 层面的 RUNNABLE 状态涵盖了 操作系统 层面的 【可运行状态】、【运行状态】和【阻塞状态】
    • 这里的阻塞是指:由于 BIO 导致的线程阻塞,在 Java 里无法区分,仍然认为 是可运行
    • 就绪状态、运行状态、正在阻塞IO的线程,统统属于Runnable状态
  • BLOCKED , WAITING , TIMED_WAITING 都是 Java API 层面对OS【阻塞状态】的细分,后面会在状态转换一节 详述

    • BLOCKED :对锁资源的等待状态
    • WAITING :没有时限的等待状态,如在线程A中,调用B.join(),线程A等待线程B运行结束,那么线程A就陷入了 WAITING 状态
    • TIMED_WAITING :有时限的等待状态,sleep(1000),那么线程在这1s内,就是TIMED_WAITING 状态

    WAITING、TIMED_WAITING 一般是线程的主动行为;而BLOCKED 一般是被动行为

  • TERMINATED 当线程代码运行结束













































状态 解释 说明
NEW 新建一个线程对象,还没有调用start()方法 new一个线程实例,线程还没有start
RUNNABLE Java线程中将就绪(READY)和运行中(RUNNING)两种状态统一为 RUNABLE 等待被调度或正在运行中
BLOCKED 表示线程阻塞于锁 线程阻塞在进入synchronized修饰的方法或代码块时的状态
WAITING 进行该状态的线程需要等待其他线程做出一些特定动作(通知或中断) 让出CPU,等待被显示的唤醒,被唤醒后进入BLOCKED状态,重新获取锁
TIMED_WAITING 不同于waiting,它可以在指定的时间后自行返回 有时限的等待状态,sleep(1000),那么线程在这1s内,就是TIMED_WAITING 状态
TERMINATED 表示显示已经执行完毕

代码实例:

  1. package com.java_thread.often_methods;
  2. /**
  3. * 线程状态(Java层面)
  4. */
  5. public class ThreadState {
  6. public static void main(String[] args) throws InterruptedException {
  7. //1、NEW
  8. Thread t1 = new Thread(() -> {
  9. });
  10. System.out.println(t1.getState());
  11. //2、RUNNING (操作系统层面的可运行、运行、阻塞三者合为RUNNING)
  12. Thread t2 = new Thread(() -> {
  13. while (true) {
  14. }
  15. });
  16. t2.start();
  17. System.out.println(t2.getState());
  18. //3、TERMINATED 已终止
  19. Thread t3 = new Thread(() -> {
  20. });
  21. t3.start();
  22. Thread.sleep(1000);
  23. System.out.println(t3.getState());
  24. //4、TIMED_WAITING 等待终止
  25. Thread t4 = new Thread(() -> {
  26. try {
  27. Thread.sleep(1000*3);
  28. } catch (InterruptedException e) {
  29. e.printStackTrace();
  30. }
  31. });
  32. t4.start();
  33. Thread.sleep(1000);
  34. System.out.println(t4.getState());
  35. //5、WAITING 等待
  36. Thread t5 = new Thread(() -> {
  37. try {
  38. //等待t2线程完成
  39. t2.join();
  40. } catch (InterruptedException e) {
  41. e.printStackTrace();
  42. }
  43. });
  44. t5.start();
  45. Thread.sleep(1000);
  46. System.out.println(t5.getState());
  47. //6、BLOCKED 受阻
  48. //test线程提前拿到锁
  49. Thread test = new Thread(() -> {
  50. synchronized (ThreadState.class) {
  51. try {
  52. Thread.sleep(1000*1000);
  53. } catch (InterruptedException e) {
  54. e.printStackTrace();
  55. }
  56. }
  57. });
  58. test.start();
  59. Thread t6 = new Thread(() -> {
  60. synchronized (ThreadState.class) {
  61. try {
  62. Thread.sleep(1000*1000);
  63. } catch (InterruptedException e) {
  64. e.printStackTrace();
  65. }
  66. }
  67. });
  68. t6.start();
  69. Thread.sleep(1000);
  70. System.out.println(t6.getState());
  71. }
  72. }

发表评论

表情:
评论列表 (有 0 条评论,196人围观)

还没有评论,来说两句吧...

相关阅读

    相关 11 线生命周期状态

    1.线程的生命周期(5种状态) 在线程的生命周期中,它会经过新建(New)、就绪(Running)、阻塞(Blocked)和死亡(Dead)五种状态。由于CPU在多条线

    相关 线生命周期状态

    自己学习时总结的线程的状态 第一步:      新建状态:使用new关键字新建线程,此时处于新建状态; 第二步:      就绪状态:当调用了该线程的start()