• 《JavaEE初阶》 Java 线程的几种状态


    目录

    一、状态列举

    二、 实例分析


    一、状态列举

    Java线程到底有几种状态,其实只要打开一下JDK源码,看一下java.lang.Thread类就知道了,java.lang.Thread定义了一个内部枚举java.lang.Thread.State,部分源码如下:

    1. /**
    2. * A thread can be in only one state at a given point in time.
    3. * These states are virtual machine states which do not reflect
    4. * any operating system thread states.
    5. * 一个线程在特定的时刻,只能有一个状态。
    6. * 这些状态是虚拟机的状态,不能反映任何操作系统的线程状态
    7. * @since 1.5
    8. */
    9. public enum State {
    10. /**
    11. * Thread state for a thread which has not yet started.
    12. * 线程未开始的状态
    13. */
    14. NEW,
    15. /**
    16. * Thread state for a runnable thread. A thread in the runnable
    17. * state is executing in the Java virtual machine but it may
    18. * be waiting for other resources from the operating system
    19. * such as processor.
    20. * 可运行的线程状态,此状态的线程正在JVM中运行,
    21. * 但也有可能在等待操作系统的其他资源,例如处理器
    22. */
    23. RUNNABLE,
    24. /**
    25. * Thread state for a thread blocked waiting for a monitor lock.
    26. * A thread in the blocked state is waiting for a monitor lock
    27. * to enter a synchronized block/method or
    28. * reenter a synchronized block/method after calling
    29. * 阻塞状态的线程在等待一个监视器锁去进入同步代码块/方法,
    30. * 或者调用后重新进入同步代码块/方法
    31. */
    32. BLOCKED,
    33. /**
    34. * Thread state for a waiting thread.
    35. * A thread is in the waiting state due to calling one of the following methods:
    36. * Object.wait()
    37. * Thread.join()
    38. * LockSupport.park()
    39. * A thread in the waiting state is waiting for another thread to
    40. * perform a particular action.
    41. * 由于调用了Object.wait()、Thread.join()、LockSupport.park()其中一个方法,线程进入等待状态
    42. * 处于等待状态的线程,正在在等待另一个线程执行特定的操作
    43. */
    44. WAITING,
    45. /**
    46. * Thread state for a waiting thread with a specified waiting time.
    47. * A thread is in the timed waiting state due to calling one of
    48. * the following methods with a specified positive waiting time:
    49. * Thread.sleep()
    50. * Object.wait()
    51. * LockSupport.parkNanos()
    52. * LockSupport.parkUntil()
    53. * 有指定等待时间的线程等待状态
    54. * 由于调用了Thread.sleep(long)、Object.wait(long)、Thread.join(long)、
    55. * LockSupport.parkNanos(long)、LockSupport.parkUntil(long)其中一个方法并传入了正(数)时间参数,
    56. * 线程处于有时间限制的等待状态
    57. */
    58. TIMED_WAITING,
    59. /**
    60. * Thread state for a terminated thread.
    61. * The thread has completed execution.
    62. * 线程已经执行完成,处于终止状态
    63. */
    64. TERMINATED;
    65. }

     

    根据上述代码,可以知道Java线程有六个状态:

    • NEW(新建)

    创建了Thread对象,但是还没调用start方法——系统内核中还该线程还没有创建出来(安排了工作,还未开始行动)

    • RUNNABLE(可运行)

    就绪状态:1、程序正在CPU上运行     2、还没在CPU上运行,但是已经准备好了(调用了start方法后——可工作的,又可以分为正在工作和即将开始工作)

    • BLOCKED(阻塞)、WAITING(等待)、TIMED_WAITING(指定时间的等待)

    阻塞状态,Java中把阻塞状态按照不同的原因又细分为三种不同状态。BLOCKED等待锁、WAITING线程中调用了wait、TIMED_WAITING线程中调用了sleep(这几个都表示排队等着其他事情)

    • TERMINATED(终止)

    系统里面的线程已经执行完毕了,销毁了(相当于线程的run执行完了,工作完成了)但是Thread对象还在

    线程之间的转换关系如下:

    值得注意的是,Java线程是不区分Ready(就绪)和Running(运行)的,它们都是Runnable状态,我把他们画出来,是为了强调,也便于理解。


     

    二、 实例分析

    🌰实例一

    线程状态:NEW -> RUNNABLE -> TERMINATED

    1. package Thread;
    2. public class demo7 {
    3. public static void main(String[] args) throws InterruptedException {
    4. Thread thread = new Thread(new Runnable() {
    5. @Override
    6. public void run() {
    7. System.out.println("该线程正在运行,thread线程状态:" + Thread.currentThread().getState().toString()); // 返回当中执行的线程对象的引用
    8. }
    9. });
    10. System.out.println("Thread被实例化,start()还未调用,thread线程状态:" + thread.getState().toString());
    11. // 程序走到这里,thread线程还未被在操作系统内核中创建,thread当前线程还是NEW
    12. thread.start();
    13. // 程序走到这里,当调用start后,thread线程开始在操作系统内核中创建,该线程所对应的PCB加入到系统链表,参与系统调度,只是参与系统调度不一定马上执行,也可能只是即将开始执行
    14. System.out.println("start()方法被调用,thread线程状态:" + thread.getState().toString());
    15. thread.join(); // main线程等thread线程执行完了后在执行
    16. System.out.println("thread线程执行完了后,thread线程状态:" + thread.getState().toString());
    17. }
    18. }

     

    🔔提醒 

    我们上述代码展示了主线程(main) 展示了thread线程的状态,注意当我们已进入主线程的入口main方法,主线程就已经被创建好了,进入了RUNNABLE状态,所有你在main打印的主线程的状态都是RUNNSABLE,不会出现NEW状态

    🌰实例二

    线程状态:NEW -> RUNNABLE -> TIMED_WAITING -> RUNNABLE -> TERMINATED

     

    1. public static void main(String[] args) throws Exception {
    2. Thread thread = new Thread(new Runnable() {
    3. @Override
    4. public void run() {
    5. System.out.println("执行run(),thread线程状态:" + Thread.currentThread().getState().toString());
    6. try {
    7. Thread.sleep(1000);
    8. } catch (InterruptedException e) {
    9. e.printStackTrace();
    10. }
    11. System.out.println("sleep结束,thread线程状态:" + Thread.currentThread().getState().toString());
    12. }
    13. });
    14. System.out.println("未调用start(),thread线程状态:" + thread.getState().toString());
    15. thread.start();
    16. // 睡眠200毫秒,让thread被调度起来,进入sleep
    17. Thread.sleep(200);
    18. System.out.println("线程sleep,thread线程状态:" + thread.getState().toString());
    19. // 睡眠2秒,让thread执行完成
    20. Thread.sleep(2000);
    21. System.out.println("线程执行完成,thread线程状态:" + thread.getState().toString());
    22. }

    执行结果

    1. 未调用start(),thread线程状态:NEW
    2. 执行run(),thread线程状态:RUNNABLE
    3. 线程sleep,thread线程状态:TIMED_WAITING
    4. sleep结束,thread线程状态:RUNNABLE
    5. 线程执行完成,thread线程状态:TERMINATED

     

    🌰实例三

    线程状态:NEW -> RUNNABLE -> BLOCKED -> RUNNABLE -> TERMINATED

    1. private static Object lock = new Object();
    2. public static void main(String[] args) throws Exception {
    3. Thread thread = new Thread(new Runnable() {
    4. @Override
    5. public void run() {
    6. System.out.println("执行run(),thread线程状态:" + Thread.currentThread().getState().toString());
    7. synchronized(lock) {
    8. }
    9. System.out.println("synchronized结束,thread线程状态:" + Thread.currentThread().getState().toString());
    10. }
    11. });
    12. System.out.println("未调用start(),thread线程状态:" + thread.getState().toString());
    13. synchronized(lock) {
    14. thread.start();
    15. Thread.sleep(200);
    16. System.out.println("线程synchronized,thread线程状态:" + thread.getState().toString());
    17. }
    18. // 睡眠2秒,让thread执行完成
    19. Thread.sleep(2000);
    20. System.out.println("线程执行完成,thread线程状态:" + thread.getState().toString());
    21. }

     

     执行结果

    1. 未调用start(),thread线程状态:NEW
    2. 执行run(),thread线程状态:RUNNABLE
    3. 线程synchronized,thread线程状态:BLOCKED
    4. synchronized结束,thread线程状态:RUNNABLE
    5. 线程执行完成,thread线程状态:TERMINATED
  • 相关阅读:
    C++11之基础篇
    Day121.ElasticSearch:概述、安装、基本操作、DSL高级查询
    MySQL存储引擎
    TensorRT Paser加载onnx 推理使用
    创建react脚手架项目——demo(react18 + react-router 6)
    java基于springboot+vue+elementui的 废品回收站管理系统
    leetcode第321场周赛
    【力客热题HOT100】-【039】98 验证二叉搜索树
    Python 使用 Tkinter库 设置 tkinter ttk 框架的背景颜色
    相机sd卡照片丢失怎么找回呢?
  • 原文地址:https://blog.csdn.net/weixin_61061381/article/details/125983330