• Java线程生命周期,及线程状态转换


    Java 并发编程主要是通过多线程实现的,而线程的操作系统中的概念。Java 中的线程其本质上就是操作系统中的线程,但是 Java 语言对操作系统的线程做了封装。

    Java 线程的生命周期,即了解线程各个节点状态的转换机制。了解 Java 线程生命周期有助于跟踪分析线程的状态,通过分析线程 dump 来解决死锁、饥饿、活锁的问题。

    Java线程的生命周期(线程状态)

    五态模型

    通用线程模型

    1. 初识状态:编程语言层面创建线程,操作系统层面未创建线程,还不允许CPU为其分配时间片。
    2. 可运行状态:操作系统层面创建线程,允许CPU为其分配之间片。
    3. 运行状态:操作系统将空闲的CPU,分配给可运行状态的线程,则线程处于运行状态。
    4. 休眠状态:运行状态的线程执行阻塞API(如I/O),或等待某个条件(如条件变量),则线程会释放CPU使用权,进入休眠状态。
    5. 终止状态:线程执行完,或者执行过程中出现异常。

    Java 线程的生命周期

    前面介绍了通用的线程生命周期模型——五态模型,编程语言会对操作系统对线程的操作进行封装,所以 Java 的生命周期模型和通用的线程生命周期模型有所不同,它有初识状态、运行/可运行状态、休眠状态和终止状态,其中休眠状态细分为 BLOCKED、WATING、TIMED_WATING,共 6 中状态,如下图所示:

    线程状态转换图

    • NEW 初始状态
    • RUNNABLE 运行/可运行状态
    • BLOCKED 阻塞
    • WATING 无线等待
    • TIMED_WATING 有时限等待
    • TERMINATED 终止状态

    Java 线程状态的转换

    从 NEW 到 RUNNABLE

    NEW 状态是在编程语言层面创建线程,而操作系统层面还没有创建线程。Java 创建线程有 3 种方式:

    1. 继承 Thread 类
    2. 实现 Runnable 接口
    3. 实现 Callable 接口

    从 NEW 状态到 RUNNABLE 状态,就是在操作系统层面创建线程,此时需要调用 Thread.start() 方法:

    MyThread myThread = new MyThread();
    // 从 NEW 状态转换到 RUNNABLE 状态
    myThread.start()

    RUNNABLE 与 BLOCKED 状态转换

    只有一种场景会触发这种转换,即线程等待 synchronized 隐式锁,此时只有一个线程能执行被 synchronized 修饰的方法或代码块,其他线程就进入 BLOCKED 状态。

    当等待的线程获得 synchronized 隐式锁时,就会从 BLOCKED 状态转换为 RUNNABLE 状态。

    RUNNABLE 与 WATING 状态转换

    有三种场景会触发这种转换。

    第一种,获取到 synchronized 隐式锁的线程调用 Object.wait() 方法,线程会从 RUNNABLE 状态转变为 WATING 状态。调用 Object.notify() 或者 Object.notifyAll() 会从 WATING 状态变为 RUNNABLE 状态。

    第二种,线程调用 Thread.join()join()是这一种线程同步的方法,当主线程调用 Thread A 的 A.join() 方法时,主线程就会从 RUNNABLE 转换为 WATING,当线程 A 执行完之后,又从 WATING 转换为 RUNNABLE。

    第三种,调用 LockSupport.park() 当前线程会阻塞,线程的状态会从 RUNNABLE 转换到 WAITING。调用 LockSupport.unpark(Thread thread) 可唤醒目标线程,目标线程的状态又会从 WAITING 状态转换到 RUNNABLE。

    RUNNABLE 与 TIMED_WATING 状态转换

    1. 调用带超时参数的 Thread.sleep(long millis) 方法;
    2. 获得 synchronized 隐式锁的线程,调用带超时参数的 Object.wait(long timeout) 方法;
    3. 调用带超时参数的 Thread.join(long millis) 方法;
    4. 调用带超时参数的 LockSupport.parkNanos(Object blocker, long deadline) 方法;
    5. 调用带超时参数的 LockSupport.parkUntil(long deadline) 方法。

    从 RUNNABLE 到 TERMINATED

    1. 执行完 run() 自然退出
    2. 执行run()时抛出异常
    3. Thread.stop() 方法,已经标记为 @Deprecated
    4. Thread.interrupt()

    相关文章

    线程的状态转换以及基本操作

    09 | Java线程(上):Java线程的生命周期

  • 相关阅读:
    MetaNamespaceKeyFunc
    golang dlv 调式成员函数
    golang 编译 添加debug gdb
    code-generator
    k8s 自定义informer
    kube-batch ——pod 和task
    kubernetes-handbook informer
    kube batch scheduler
    k8s-scheduler-extender-example
    volcano 快速开始
  • 原文地址:https://www.cnblogs.com/shuiyj/p/13185082.html
Copyright © 2020-2023  润新知