【Java】线程状态:线程生命周期的六个阶段

news2024/12/23 22:39:09

欢迎浏览高耳机的博客

希望我们彼此都有更好的收获

感谢三连支持!

在Java中,线程可以处于多种状态,这些状态描述了线程的生命周期。了解这些状态及其转换条件对于编写高效且无错误的多线程应用程序至关重要。本文将总结Java线程的几种状态,每种状态的含义,以及状态之间的切换条件。

线程状态的种类及含义

Java线程的状态主要有以下几种:

  1. 新建状态(New):线程对象已被创建,但还没有调用start()方法。
  2. 可运行状态(Runnable):线程已经调用了start()方法,可能正在运行,也可能正在等待CPU时间片。
  3. 阻塞状态(Blocked):线程因为等待监视器锁(即等待某个同步锁)而进入阻塞状态,它在等待获取该资源的锁。
  4. 等待状态(Waiting):线程通过调用wait()join()或者LockSupport.park()方法进入等待状态,需要其他线程通知或中断才能返回。
  5. 计时等待状态(Timed Waiting):线程通过调用sleep(long millis)wait(long timeout)join(long millis)LockSupport.parkNanos()}LockSupport.parkUntil()等方法,进入计时等待状态,与等待状态类似,但是有最大时间限制,超过时间后会自动唤醒。
  6. 终止状态(Terminated):线程的run()方法执行结束,或者因异常退出了run()方法。

状态之间的切换条件

  1. 从新建到可运行:调用线程的start()方法。
  2. 从可运行到阻塞:线程尝试获取一个已经被其他线程持有的锁。
  3. 从可运行到等待:调用wait()join()LockSupport.park()方法。
  4. 从可运行到计时等待:调用sleep(long millis)wait(long timeout)join(long millis)LockSupport.parkNanos()}LockSupport.parkUntil()方法。
  5. 从等待到可运行:其他线程调用了当前线程的notify()notifyAll()方法,或者当前线程的LockSupport.unpark(Thread)被调用。
  6. 从计时等待到可运行:等待时间结束,线程自动唤醒。
  7. 从可运行到终止:线程执行完run()方法,或者在run()方法中发生未捕获的异常。
  8. 从阻塞到可运行:线程成功获取到锁,锁被释放后线程可以继续执行。

以下是线程状态的转换代码示例:

  1. 新建到可运行(NEW -> RUNNABLE)
public class ThreadStateExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("Thread is running");
        });
        System.out.println("Thread state before start: " + thread.getState()); // NEW
        thread.start();
        System.out.println("Thread state after start: " + thread.getState()); // RUNNABLE
    }
}
  1. 可运行到终止(RUNNABLE -> TERMINATED)
public class ThreadStateExample {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            System.out.println("Thread is running");
        });
        thread.start();
        thread.join(); // 等待线程结束
        System.out.println("Thread state after thread.join: " + thread.getState()); // TERMINATED
    }
}
  1. 可运行到等待(RUNNABLE -> WAITING)
public class ThreadStateExample {
    private static final Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            synchronized (lock) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        Thread.sleep(1000); // 确保线程进入WAITING状态
        System.out.println("Thread state: " + thread.getState()); // WAITING
    }
}
  1. 可运行到计时等待(RUNNABLE -> TIMED_WAITING)
public class ThreadStateExample {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            try {
                Thread.sleep(5000); // 线程进入计时等待状态
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        thread.start();
        Thread.sleep(1000); // 确保线程进入TIMED_WAITING状态
        System.out.println("Thread state: " + thread.getState()); // TIMED_WAITING
    }
}
  1. 可运行到阻塞(RUNNABLE -> BLOCKED)
public class ThreadStateExample {
    private static final Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(() -> {
            synchronized (lock) {
                try {
                    Thread.sleep(10000); // 持有锁并休眠
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread thread2 = new Thread(() -> {
            synchronized (lock) { // 尝试获取已被thread1持有的锁,因此进入BLOCKED状态
                // 执行相关操作
            }
        });
        thread1.start();
        Thread.sleep(1000); // 确保thread1持有锁
        thread2.start();
        Thread.sleep(1000); // 确保thread2尝试获取锁
        System.out.println("Thread2 state: " + thread2.getState()); // BLOCKED
    }
}

 


希望这篇博客能为你理解线程状态提供一些帮助。

如有不足之处请多多指出。

我是高耳机。

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

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

相关文章

半导体制造技术中的沉积和驱入(Deposition and drive-in)过程

来源:半导体制造技术导论——萧宏 沉积和驱入过程 图5.34 硼掺杂工艺高温扩散炉系统示意图 图5.35 扩散掺杂工艺流程 图5.36 扩散工艺在超浅结深(USJ)上的应用

C++设计模式——Prototype Pattern原型模式

一,原型模式的定义 原型模式是一种创建型设计模式,它允许通过克隆已有对象来创建新对象,从而无需调用显式的实例化过程。 原型模式的设计,使得它可以创建一个与原型对象相同或类似的新对象,同时又可以减少对象实例化…

项目实战应用Redis分布式锁

Redis分布式锁 一、前言二、Redis分布式锁过期处理三、Redis分布式实现3.1 基于Jedis 的API实现分布式锁3.1.1 基础命令3.1.2 基于Jedis API的分布式锁3.1.3 基于Lua脚本实现分布式锁 四、Redisson的使用五、Redision锁 核心源码分析六、总结 一、前言 对于项目中使用Redis分布…

jdk相关介绍

JDK,全称Java Development Kit,是Java语言开发的基础工具包。它包含了Java运行时环境(JRE)以及用于开发Java应用程序的各种工具和库。JDK为Java程序员提供了编译、调试和运行Java应用程序所需的全部环境。 JDK的主要组成部分包括&…

OpenCV_图像像素读写操作

本文详细介绍了如何在C项目中使用OpenCV进行图像像素的读写操作,包括使用头文件声明Pixel类,通过遍历和指针方式处理灰度图和彩色图,以及在主函数中调用这些操作。 数组遍历的方式进行图像像素读写 void QuickDemo::pixelVisit_Demo(Mat&am…

【最新华为OD机试E卷-支持在线评测】增强的strstr(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…

替换 Oracle ,江河信息用 TDengine 解决高基数查询写入问题

在数字经济快速发展的背景下,智慧水利作为重要的基础设施之一,正逐步成为提升水资源管理效率、优化生态环境的重要力量。江西省水投江河信息技术有限公司(以下简称“江河信息”)作为高新技术国有企业,坚定致力于打造数…

监控binlog日志监控表变化进行消息通知

前言 由于我们做项目的时候有项目任务管理工具,目前用的最多的是禅道,而我们用的是redmine,而redmine是使用ruby写的,刚好我们这边没有会用ruby的人,所以就有了这样一个小工具,用于监控binlog日志通过钉钉…

机器人相关知识的本身和价值

简要将人类简史分为 农业工业信息智能 四个时代。 在信息时代,知识本身就可以等同于价值。 常识看,学历可以变现,高品质文凭能极大概率获得工资远远高于平均值的工作机会。 在智能时代,知识本身毫无价值,知识的应…

UML 类图(提供 Java 实现)

文章目录 UML 类图概述及作用类图表示法类(接口)的表示类与类之间关系的表示关联关系(Association)单向关联(Unidirectional Association)双向关联(Bidirectional Association)自关联…

大学生看过来,必备4款写论文AI写作网站先稿后付

在当今学术研究和写作领域,AI论文写作工具的出现极大地提高了写作效率和质量。这些工具不仅能够帮助研究人员快速生成论文草稿,还能进行内容优化、查重和排版等操作。其中,千笔-aipasspaper是一个备受推荐的平台,它结合了先稿后付…

7.2 溪降技术:下攀

目录 7.2 下攀概述视频课程观看电子书:下攀 一级风险评估装备个人动作技术:面壁下攀烟囱下攀 协助队友总结 7.2 下攀 概述 下攀可能是峡谷探险中最被低估的技能。峡谷中经常存在可以下攀的小落差,这种方式比设置绳索快得多。一组熟练的下攀者能迅速完成…

JavaScript高级——闭包的理解

1、如何产生闭包? —— 当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包。 2、闭包到底是什么? —— 使用 chrome 查看 —— 理解一&a…

字符编码发展史1 — ASCII和EASCII

1. 字符集与字符编码 1.1. 字符集1.2. 字符编码1.3. 两者的关系 2. 字符编码的发展历史 2.1. 第一个阶段 ASCII编码 2.1.1. ASCII2.1.2. EASCII 1. 字符集与字符编码 1.1. 字符集 字符集(Charcater Set或Charset): 是一个系统支持的所有…

【AI小项目5】使用 KerasNLP 对 Gemma 模型进行 LoRA 微调

目录 一、项目简介概述时间主要工作和收获技术栈数据集结果参考 二、完整代码概览设置安装依赖选择一个后端导入包 加载数据集加载模型微调前的推理欧洲旅行例子光合作用例子 LoRA 微调微调后的推理欧洲旅行例子光合作用例子 改进方向 三、背景知识补充Fine-tune(微…

数据结构(2):LinkedList和链表[2]

我们在上一篇文章中着重讨论了单链表的实现。其中我们要注意单链表进行遍历时一步一步走的思想。那么这篇文章我们将继续讨论链表的更多内容,那就让我们开始吧。 1.经典单链表算法题 我们将通过几个经典的题对单链表进行进一步的认识。 (1)反转链表 206. 反转链…

2024年上海初中生古诗文大会倒计时一个半月:做一做2024官方模拟题

2024年上海市初中生古诗文大会自由报名活动的初赛日期于11月3日开始,距离今天大概一个半月。 如何准备2024年初中生古诗文大会的自由报名初选呢?吃透(记熟)2024年初中生古诗文阅读专辑上的题目、知识点和往年真题及知识点。 有许…

Python数据分析-世界上最富有的1000人

一、研究背景 随着全球化的加速发展和技术的进步,财富分配问题日益成为全球关注的焦点。财富的不平等现象日益明显,少数极富有的个人掌握了全球大部分的财富资源。了解全球最富有个人的财富分布及其背后的行业和国家因素,对于分析全球经济趋…

Element-ui el-table 全局表格排序

实现效果如下&#xff1a; 一、当页数据排序 如果只想要当前页面排序&#xff0c;只会涉及到前端&#xff0c;只需在<el-table-column>标签上添加 :sortable"true"即可 二、自定义排序 如果想要全局排序&#xff0c;需要自定义排序函数&#xff0c;请求后台排…

Linux基础---10进程管理

一.查看和关闭进程 1.查看进程 基础指令: ps -efPID 进程编号&#xff0c;PPID 父进程编号&#xff0c; CMD命令名称 进阶指令–查看进程的树形结构&#xff1a; yum install psmisc -y #首先安装psmisc后可直接使用pstreepstree2.关闭进程 要想关闭某个或多个进程需要知道…