Java并发编程:线程生命周期

Java并发编程专栏

文章收录于Java并发编程专栏


线程生命周期

  线程是Java并发编程的核心概念,理解线程生命周期对于编写高效的并发程序至关重要。本文将详细介绍 Java 线程的六种状态以及状态之间的转换关系,帮助读者更好地理解线程的行为。
  在Java中JVM将线程按照生命周期划分为了四大种类:运行、等待、阻塞和结束,其中运行分为就绪(READY)和运行中中(RUNNING),阻塞分为等待(WAITING)和超时等待(TIMED_WAITING)。六种状态:NEW(初始化状态)、RUNNABLE(可运行/运行状态)、BLOCKED(阻塞状态)、WAITING(无时限等待)、TIMED_WAITING(有时限等待)和TERMINATED(终止状态)。

初始状态(NEW)

  在Java中不管通过何种手段创建的Thread对象,都会处于初始状态。在初始状态下的线程是不会执行的,只有当调用线程的start()方法,将线程状态从初始状态(NEW)切换到运行状态(RUNNABLE),然后等到资源分配后方可正在的运行。

运行状态(RUNNABLE)

  运行状态分为运行中(RUNNING)和就绪(READY)两个状态,其中运行中状态表示当前线程被系统调度后正在运行,就绪状态表示当前线程已经做好运行的准备,等待系统调度后运行。
  处于就绪状态的线程被系统调度之后就会切换到运行中状态,如果处于运行中状态的线程被yield()方法调用,就会释放CPU资源然后切换到就绪状态,但不会释放所持有的锁。

阻塞状态(BLOCKED)

  阻塞状态(BLOCKED)表示当前线程正在等待锁资源,只要处于阻塞状态的线程获得到所需要的锁资源之后,就会立刻切换到运行状态(RUNNABLE)。从运行状态(RUNNABLE)切换到阻塞状态(BLOCKED)只存在一种场景,就是线程等待synchronized的隐式锁。

线程调用阻塞式API时,是否会转换到阻塞状态(BLOCKED)?

  操作系统线程中,如果处于运行状态的线程调用阻塞API后,线程状态会转换为休眠状态。但是JVM定义并非如此,线程调用阻塞API后线程状态不会发生变化,即Java线程的状态依然保持在RUNNABLE,JVM将调用阻塞API的线程状态视为RUNNABLE,但并不意味着线程实际上在运行。
  线程调用阻塞式API,表示当前线程等待CPU的使用权或者等待I/O,其在操作系统层面处于休眠状态,但是JVM并不关心操作系统层面的相关状态,对于它来说不管是等待CPU还是等待I/O都是等待被执行,都应该归入了运行状态(RUNNABLE)。所以线程调用阻塞API后线程状态不会发生变化,即Java线程的状态依然保持在运行状态(RUNNABLE)。

等待状态(WAITING)

  当前线程放弃所持有的锁就会进入等待状态(WAITING),从运行状态(RUNNABLE)进入等待状态(WAITING)会有三种情况:

  1. synchronized块中调用Object.wait()方法
  2. 调用Thread.join()方法
  3. 调用LockSupport.park()方法

  调用LockSupport.park()方法当前线程会阻塞,线程的状态从运行状态(RUNNABLE)切换到等待状态(WAITING)。调用LockSupport.unpark(Thread thread)唤醒目标线程,目标线程的状态就会从等待状态(WAITING)转换到运行状态(RUNNABLE),再获取到资源后执行。

超时等待状态(TIMED_WAITING)

  超时等待状态(TIMED_WAITING)和等待状态(WAITING)一样,只是超时等待到了等待时间之后会自动进入运行状态(RUNNABLE),进入超时等待状态(TIMED_WAITING)有五种情况:

  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) 方法

终止状态(TERMINATED)

  线程执行完毕或者被异常中断就会进入终止状态(TERMINATED),Java的Thread类提供了stop() 方法可以切换到终止状态(已经标记为@Deprecated),现在正确的姿势是调用interrupt()中断方法。

stop()和interrupt()方法的区别

  stop()方法不给线程任何喘息的机会,会直接杀死线程。如果被stop的线程持有ReentrantLock锁,那么该线程不会主动调用ReentrantLock的unlock()去释放锁,这样一来其他线程就再也没有机会获得ReentrantLock锁。所以该方法被标记为@Deprecated不再建议使用,类似的方法还有suspend()和resume()。
  interrupt()方法不会像stop一样立即杀死线程,它仅是通知线程中断,这样一来线程就有执行后续操作的机会,同样也可以选择无视这个通知,被interrupt的线程采用异常和主动检测两种方式来获得interrupt发出的中断通知。

使用interrupt的注意事项

  使用interrupt中断线程需特别注意,当有抛出InterruptedException异常,try catch捕捉此异常时,应在catch中重置线程的中断标示。因为抛出异常后中断标示会自动清除掉。如果像以下代码那样处理,因为catch中没有e.interrupt()重置线程e的中断标示,代码就会进入无限循环。

Thread e = new Thread(() ->{
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e1) {
        e1.printStackTrace();
    }
    System.out.println("e .....");
});

e.start();
Thread.sleep(1000);
e.interrupt();

while (true){
    System.out.println(e.isInterrupted());
    if(e.isInterrupted()){
        System.out.println("e Interrupted....");
        break;
    }

    try {
        Thread.sleep(100);
        throw new InterruptedException("123");
    }catch (InterruptedException ie){
        // 重置线程e中断标示
        e.interrupt();
        ie.printStackTrace();
    }
}

一键三连,让我的信心像气球一样膨胀!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql8.0中的mysql.ibd

mysql8.0版本中多了一个mysql.ibd的文件。5.7版本则没有这个文件。 MySQL5.7: .frm文件 存放表结构信息 .opt文件,记录了每个库的一些基本 信息,包括库的字符集等信息 .TRN,.TRG文件用于存放触发器的信 息内容。 在MySQL 8.0之前&#xff0…

2002NOIP普及组真题 4. 过河卒

线上OJ 地址: 【02NOIP普及组】过河卒 核心思想: 对于此类棋盘问题,一般可以考虑 dp动态规划、dfs深搜 和 bfs广搜。 解法一:dp动态规划 方法:从起点开始逐步计算到达每个位置的路径数。对于每个位置,它…

数 据 类 型

概述 Java 是强类型语言。 每一种数据都定义了明确的数据类型,在内存中分配了不同大小的内存空间(字节)。 Java 中一共有 8 种基本类型(primitive type),包括 4 种整型、2 种浮点型、1 种字符类型&#…

HikariCP连接池初识

HikariCP的简单介绍 hikari-光,hikariCP取义:像光一样轻和快的Connetion Pool。这个几乎只用java写的中间件连接池,极其轻量并注重性能,HikariCP目前已是SpringBoot默认的连接池,伴随着SpringBoot和微服务的普及&…

【ai】pycharm远程ssh开发

方式1: gateway的方式是远程放一个pycharm 专业版,经常下载失败 方式2: 类似vs,源码本地,同步到远程进行运行。 参考大神的分享: Pycharm远程连接服务器(2023-11-9) Pycharm远程连接服务器(windows下远程修改服务器代码)[通俗易懂] cpolar 建议同时内网穿透 选 远程开…

详解 Flink 的状态管理

一、Flink 状态介绍 1. 流处理的无状态和有状态 无状态的流处理:根据每一次当前输入的数据直接转换输出结果的过程,在处理中只需要观察每个输入的独立事件。例如, 将一个字符串类型的数据拆分开作为元组输出或将每个输入的数值加 1 后输出。…

Pycharm中import torch报错解决方案(Python+Pycharm+Pytorch cpu版)

pycharm环境搭建完毕后,编写一个py文件demo,import torch报错,提示没有。设置python解释器: 选择conda环境,使用现有环境,conda执行文件找到Anaconda安装路径下Scripts文件夹内的conda.exe,最后…

程控直流电源:助力企业实现绿色转型与可持续发展

一、程控直流电源发展趋势 1. 程控直流电源的高效节能 在全球能源紧张、环境污染严重的背景下,高效节能成为电源行业的重要发展方向。程控直流电源采用先进的电源管理技术,实现了高效率、低功耗的目标。未来,随着技术的不断进步&#xff0c…

英语学习笔记33——A fine day

A fine day 风和日丽 词汇 Vocabulary day n. 日子,白天 复数:days 常见节日:Mothers’ Day 母亲节      Fathers’ Day 父亲节      Teachers’ Day 教师节      Children’s Day 儿童节      Women’s Day 妇女节 c…

IO流字符流(FileReader与FileWriter)

目录 FileReader 空参read方法 带参read方法👇 FileWriter void write(intc) 写出一个字符 void write(string str) 写出一个字符串 void write(string str,int off,int len) 写出一个字符串的一部分 void write(char[] cbuf) …

入门matlab

常识 如何建一个新文件 创建新文件,点击新建,我们就可以开始写代码了 为什么要在代码开头加入clear 假如我们有2个文件,第一个文件里面给x赋值100,第二个文件为输出x 依次运行: 结果输出100,这是因为它们…

less---20-28

less-20 这关登陆成功会显示cookie,所以抓包在cookie处注入 less-21 这关登陆成功会显示cookie,所以抓包在cookie处注入,发现不成功,查看代码发现被编码 先对注入语句进行base64编码再注入 less-22 闭合字符",同21关 less-23 这关查看代码发现…

高并发ping多台主机IP

简介 社区或者是大型公司往往有成千上万或者几百台设备,保持设备始终在线对网络运维人员来说至关重要,然而一个一个登录检查,或者一个一个ping并不明智,累人且效率极低,并出错率高。花钱买检测服务当我没说。 shell编…

C++【STL】改造红黑树简单模拟实现set map(带你了解set map的底层实现结构)

目录 一、学前铺垫(泛型编程) 二、改造红黑树 1.红黑树节点的改造 2.insert的改造 3.迭代器的实现 4.完整改造代码 三、set的模拟实现封装 四、map的模拟实现封装 五、完结撒❀ 前言: 下面为了简单模拟实现set map所出现的代码是以…

【诈骗离你我很近】中国同胞进来看看国外诈骗新套路。

前几天一个老外经常在CSDN给我发消息,我最开始很警惕,不过聊了大概半个月,我就没怎么怀疑他了,而且还很高兴认识了一个外国朋友。这半个月聊天内容很正常,就聊些中国的小习惯,让我教他用筷子。还问我有哪些…

算法家族之一——二分法

目录 算法算法的打印效果如果算法里的整型“i”为1如果算法里的整型“i”为11 算法的流程图算法的实际应用总结 大家好&#xff0c;我叫 这是我58&#xff0c;现在&#xff0c;请看下面的算法。 算法 #define _CRT_SECURE_NO_WARNINGS 1//<--预处理指令 #include <stdi…

实现手机空号过滤或手机号码有效性验证

手机空号过滤或手机号码有效性验证通常涉及使用专门的API接口来查询手机号码的状态。这些API接口通常由第三方服务提供商提供&#xff0c;它们会与电信运营商合作或利用自己的数据库来验证手机号码是否真实存在、是否已被分配、是否处于空号状态等。 以下是一些步骤和考虑因素…

Java:111-SpringMVC的底层原理(中篇)

这里续写上一章博客&#xff08;110章博客&#xff09;&#xff1a; 现在我们来学习一下高级的技术&#xff0c;前面的mvc知识&#xff0c;我们基本可以在67章博客及其后面相关的博客可以学习到&#xff0c;现在开始学习精髓&#xff1a; Spring MVC 高级技术&#xff1a; …

黑马程序员——Spring框架——day07——SpringBoot高级

目录&#xff1a; SpringBoot自动化配置原理 starter依赖管理机制自动化配置初体验Configuration配置注解Import注解使用1Import注解使用2Conditional衍生条件装配ConfigurationProperties配置绑定SpringBootApplication入口分析EnableAutoConfiguration自动配置注解按条件开启…

指针(初阶2)“野指针以及指针运算”

目录 一.野指针 二.如何避免野指针 三.指针运算 1、指针&#xff08;-&#xff09;整数 2、指针 - 指针 3、指针关系运算 小编在这里声明一下&#xff0c;将某一块的知识点分为上中下或者1&#xff0c;2&#xff0c;3来编写不是为了增加小编的文章总量&#xff0c;也不是故意这…