Java基础夯实——2.4 线程的生命周期

news2024/11/20 11:57:53

在这里插入图片描述

Java线程生命周期

Java线程的生命周期分为:新建(New)就绪(Runnable)阻塞(Blocked)等待 (Waiting)计时等待(Timed_Waiting)终止(Terminated) 六种状态,这些状态通过Thread.State枚举类定义。

1. 新建状态(New)

  • 当一个线程对象被创建但尚未调用start()方法时,线程处于新建状态

  • 在这个阶段,线程对象仅存在于内存中,但尚未与操作系统的底层线程关联。

  • 可以为线程设置名称、优先级等属性,但线程未开始执行。

  • 状态特点

    • 调用start()方法后会转移到就绪状态
    • 如果没有调用start()方法就试图调用join()interrupt(),将抛出异常。
  • 示例

public class ThreadLifecycleExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> System.out.println("Thread is running."));
        // 线程处于新建状态
        System.out.println("Thread State: " + thread.getState()); // 输出 NEW
    }
}

2. 就绪状态(Runnable)

  • 调用start()方法后,线程进入就绪状态

  • 此时线程已交给操作系统线程调度器管理,但未必立即运行。

  • 线程调度器根据算法(如时间片轮转)决定何时将线程分配到CPU。

  • 状态特点

    • 此状态不等同于“运行中”,线程可能随时等待被调度。
    • 调用start()后,无法再次调用该方法,否则会抛出IllegalThreadStateException
  • 示例

public class ThreadLifecycleExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("Thread is running.");
        });
        thread.start();
        System.out.println("Thread State after start(): " + thread.getState()); // 输出 RUNNABLE
    }
}

3. 运行状态(Running)

  • 当线程获得CPU时间片后,线程进入运行状态

  • 此时线程执行其run()方法中的任务。

  • 线程调度器可能在运行状态下暂停线程,并将其转移回就绪状态以让其他线程运行。

  • 状态特点

    • 开发者无法显式设置线程为运行状态,状态完全由操作系统调度决定。
    • 多线程环境下,运行状态的线程可能随时被挂起。
  • 代码示例

public class ThreadLifecycleExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("Thread State: " + Thread.currentThread().getState()); // 输出 RUNNABLE 或运行中
        });
        thread.start();
    }
}

4. 等待/阻塞/计时等待状态

线程可能因资源或时间限制无法继续运行时,会进入以下三种状态:

(1)等待状态(Waiting)

  • 线程无限期地等待另一个线程唤醒它。

  • 通常是通过Object.wait()Thread.join()进入。

  • 唤醒方式包括调用notify()notifyAll()

  • 状态特点

    • 无法自行恢复,必须由另一个线程显式唤醒。
    • 常用于线程间协作。
  • 示例

public class WaitingExample {
    public static void main(String[] args) throws InterruptedException {
        Object lock = new Object();
        Thread thread = new Thread(() -> {
            synchronized (lock) {
                try {
                    System.out.println("Thread is waiting.");
                    lock.wait(); // 线程进入等待状态
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread resumed.");
            }
        });

        thread.start();
        Thread.sleep(1000); // 主线程暂停1秒
        synchronized (lock) {
            lock.notify(); // 唤醒等待线程
        }
    }
}

(2)计时等待状态(Timed Waiting)

  • 线程等待一段时间后会自动唤醒。

  • 调用如Thread.sleep()join(timeout)wait(timeout)方法会进入该状态。

  • 状态特点

    • 无需显式唤醒,时间结束后线程自动进入就绪状态
    • 常用于延时操作。
  • 示例

public class TimedWaitingExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            try {
                System.out.println("Thread is sleeping.");
                Thread.sleep(2000); // 线程进入计时等待状态
                System.out.println("Thread woke up.");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        thread.start();
    }
}

(3)阻塞状态(Blocked)

  • 当一个线程试图进入被其他线程持有的同步代码块时,会进入阻塞状态。

  • 一旦锁被释放,线程将进入就绪状态等待调度。

  • 状态特点

    • 阻塞是由于线程竞争共享资源而导致的。
    • 常见于synchronized关键字或锁机制。
  • 示例

public class BlockedExample {
    public static void main(String[] args) {
        Object lock = new Object();

        Thread thread1 = new Thread(() -> {
            synchronized (lock) {
                try {
                    Thread.sleep(5000); // 保持锁5秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("Thread 2 acquired the lock.");
            }
        });

        thread1.start();
        thread2.start();
    }
}

5. 终止状态(Terminated)

  • 描述

    • 当线程执行完成或因异常退出时,进入终止状态
    • 终止后的线程无法再次启动。
  • 状态特点

    • 使用isAlive()方法可以检查线程是否仍存活。
    • 线程终止后,它的资源会被JVM回收。
  • 代码示例

public class TerminatedExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> System.out.println("Thread is running."));
        thread.start();

        try {
            thread.join(); // 等待线程终止
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Thread State: " + thread.getState()); // 输出 TERMINATED
    }
}

常见问题

1. 线程的生命周期包括哪几个阶段?**

New : 为线程分配内存并初始化其成员变量值
Runnable:JVM完成方法调用栈和程序计数器创建,等待线程调用和运行
Blocked:主动或被动放弃CPU使用权并暂停运行
Waiting:等待
Timed_Waiting:超时后会被自动唤醒
Terminated:正常或者异常结束或者手动结束

2. 在哪些情况下会出现线程阻塞?

线程阻塞(Blocked)通常发生在以下几种场景中:

  1. 等待锁:
    • 一个线程试图进入由synchronized关键字保护的代码块或方法,但锁已被其他线程持有,当前线程将进入阻塞状态。
    • 示例:
      synchronized (lock) {
          // 当前线程执行时,其他线程试图进入会阻塞
      }
      
  2. I/O操作:
    • 线程等待输入/输出完成时,如从文件或网络读取数据。
  3. 线程阻塞工具类:
    • 使用Lock或类似机制时,线程可能因为未能获取锁而被阻塞。
    • 示例:
      Lock lock = new ReentrantLock();
      lock.lock(); // 其他线程会在这里阻塞
      
  4. 其他同步机制:
    • 使用CountDownLatchSemaphore等并发工具,线程可能会因未满足条件而阻塞。

3. 线程在就绪状态下会立即执行吗?

不会 线程处于就绪状态时,已经准备好运行,但是否执行取决于线程调度器的安排。
线程调度器根据操作系统的调度策略(如时间片轮转或优先级)决定何时将线程分配到CPU。
如果有多个线程处于就绪状态,它们需要等待调度。

4. 什么是线程阻塞?

**线程阻塞(Blocked)**是指线程因为某种原因被挂起,无法继续执行,直到某些条件满足为止。

  • 触发原因:
    1. 等待锁: 线程试图进入被其他线程持有的synchronized代码块或方法。
    2. 资源不可用: 线程等待特定资源(如文件、网络数据)。
    3. 线程竞争: 线程因并发控制工具(如锁、信号量)而受阻。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2244016.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实现简易计算器 网格布局 QT环境 纯代码C++实现

问题:通过代码完成一个10以内加减法计算器。不需要自适应,界面固定360*350。 ""按钮90*140,其它按钮90*70。 参考样式 #define DEFULT_BUTTON_STYLE "\ QPushButton{\color:#000000;\border:1px solid #AAAAAA;\border-radi…

RNN公式解释:实现记忆功能;RNN的状态向量

目录 RNN公式解释:实现记忆功能 一、词向量 二、RNN的状态向量 三、词向量变为状态向量的过程 四、总结 RNN公式解释:实现记忆功能 在RNN(递归神经网络)中,词向量变为状态向量的过程,实际上是RNN处理时序数据的一个核心环节。以下是对这一过程的详细解释: 一、词向…

【Linux】基础02

Linux编译和调试 VI编辑文件 vi : 进入文件编辑 是命令行模式 i :从光标处进入插入模式 dd : 删除光标所在行 n dd 删除指定行数 Esc : 退出插入模式 : 冒号进入末行模式 :wq : 保存退出 :q : 未修改文件可以退出 :q! …

21.UE5游戏存档,读档,函数库

2-23 游戏存档、读档、函数库_哔哩哔哩_bilibili 目录 1.存档蓝图 2.函数库 2.1保存存档 2.2读取存档: 3.加载游戏,保存游戏 3.1游戏实例对象 3.2 加载游戏 3.3保存游戏 这一节的内容较为错综复杂,中间没有运行程序进行阶段性成果的验…

未来已来:少儿编程竞赛聚焦物联网,激发创新潜力

随着人工智能与物联网技术(IoT)的快速发展,少儿编程教育正在迎来新的变革浪潮。近年来,各类少儿编程竞赛纷纷增加了物联网相关主题,要求学生结合编程知识和硬件设备设计智能家居、智慧城市等创新项目。这一趋势不仅丰富…

布局设计器

介绍 最近遇到一个设计器的需求,要求拖拽布局,图层管理,自定义组件预览,分辨率等等功能。说白了就是先用设计器布局然后在屏幕上播放你布局好的内容 所以不多说了直接上代码 代码地址 这里大概说下有哪些功能吧 图层与属性框的值关…

Java中日志采集框架-JUL、Slf4j、Log4j、Logstash

1. 日志采集 日志采集是指在软件系统、网络设备、服务器或其他IT基础设施中自动收集日志文件和事件信息的过程。这些日志通常包含了时间戳、事件类型、源和目标信息、错误代码、用户操作记录等关键数据。日志采集的目的是为了监控系统运行状态、分析系统性能、审计用户行为、故…

ansible从入门到精通(完整篇)

ansible从入门到精通(完整篇) 转自ansible从入门到精通(完整篇) 文章目录 01 Ansible介绍与安装 1. 介绍 Ansible 1.1 什么是 Ansible?1.2 Ansible 无需代理1.3 Ansible 方式 2. 安装 Ansible 2.1 控制节点2.2 受管主机2.3…

Python自学之Colormaps指南

目录 1.色彩映射表(Colormaps)是什么? 2.Matplotlib中的色彩映射表类型 2.1同色渐变(Sequential Colormaps) 2.2双色渐变(Divergence Colormaps) 2.3定性色彩(Qualitative Col…

CentOS 环境下通过 YUM 安装软件

操作场景 为提升用户在云服务器上的软件安装效率,减少下载和安装软件的成本,腾讯云提供了 YUM 下载源。在 CentOS 环境下,用户可通过 yum 命令快速安装软件。对于 YUM 下载源,用户不需要添加软件源,可以直接安装软件包…

手机远程控制电脑,让办公更快捷

在数字化办公的浪潮下,远程控制软件已成为连接工作与生活的桥梁。它使得用户能够通过一台设备(主控端)来操作另一台设备(被控端),无论它们是否位于同一局域网内。这种软件广泛应用于远程办公、手机远程控制…

WebRTC实现双端音视频聊天(Vue3 + SpringBoot)

目录 概述 相关概念 双端连接整体实现步骤概述 文章代码实现注意点 STUN和TURN服务器的搭建 开发过程描述 后端开发流程 前端开发流程 效果演示 Gitee源码地址 概述 文章描述使用WebRTC技术实现一对一音视频通话。 由于设备摄像头限制(一台电脑作测试无法…

[C++]:C++11(二)

1. 左值与右值 1.1 左值与右值的概念 左值:左值本质上是一个表示数据的表达式,常见的如变量名或者解引用后的指针等形式。它具备以下显著特点: 可被取地址:能够通过取地址操作符 & 获取其内存地址,这意味着它在内…

Acme PHP - Let‘s Encrypt

Lets Encrypt是一个于2015年三季度推出的数字证书认证机构,旨在以自动化流程消除手动创建和安装证书的复杂流程,并推广使万维网服务器的加密连接无所不在,为安全网站提供免费的SSL/TLS证书。 使用PHP来更新证书: Acme PHP | Rob…

探索 HTML 和 CSS 实现的 3D旋转相册

效果演示 这段HTML与CSS代码创建了一个包含10张卡片的3D旋转效果&#xff0c;每张卡片都有自己的边框颜色和图片。通过CSS的3D变换和动画&#xff0c;实现了一个动态的旋转展示效果 HTML <div class"wrapper"><div class"inner" style"-…

Cargo Rust 的包管理器

Cargo->Rust 的包管理器 Cargi简介Cargo 的主要功能1. 创建项目2. 管理依赖3. 构建项目4. 运行项目5. 测试代码6. 检查代码7. 生成文档8. 发布和分享包 Cargo 的核心文件1. Cargo.toml2. Cargo.lock **Cargo 的生态系统** 常用命令总结Hello, Cargo! 示例 Cargi简介 Cargo …

代码随想录算法训练营第三十五天| 01背包问题 二维 、01背包问题 一维、416. 分割等和子集 。c++转java

背包理论基础 视频地址&#xff1a; 带你学透0-1背包问题&#xff01;| 关于背包问题&#xff0c;你不清楚的地方&#xff0c;这里都讲了&#xff01;| 动态规划经典问题 | 数据结构与算法_哔哩哔哩_bilibili 01背包问题 二维 题目我是在Acwing上面做的&#xff0c;思路可以…

亚马逊云科技宣布新推出Elasticahe for Redis的 Valkey缓存

Amazon ElastiCache 宣布支持 Valkey&#xff0c;与其他支持的引擎相比&#xff0c;无服务器的价格低 33%&#xff0c;基于节点的价格低 20%。使用 ElastiCache Serverless for Valkey&#xff0c;客户可以在一分钟内创建缓存&#xff0c;并且起步价低至每月 6 USD。Valkey 是由…

SpringBoot3.x.x整合Ehcache3 实例(入门踩坑教程)

近期尝试了一下 SpringBoot 3.3.5 JDK17 Ehcache3.10.8整合 注意&#xff0c;这个版本的boot&#xff0c;提出了公用的缓存模板&#xff0c;Spring官网有相关介绍&#xff0c;整合ehcache需要使用jcache。 老版本的3.0版本以下整合&#xff0c;我这里就不参与了&#xff0c;可以…

跨平台WPF框架Avalonia教程 十六

SelectableTextBlock 可选文本块 SelectableTextBlock 块是一个用于显示文本的标签&#xff0c;允许选择和复制文本。它可以显示多行&#xff0c;并且可以完全控制所使用的字体。 有用的属性​ 您可能最常使用这些属性&#xff1a; 属性描述SelectionStart当前选择的起始字…