JavaEE初阶——多线程(二)

在这里插入图片描述

T04BF

👋专栏: 算法|JAVA|MySQL|C语言

🫵 小比特 大梦想

此篇文章延续上一篇文章,与大家分享Thread常见的方法以及线程的状态相关知识
其他内容我们下一篇再见!
如果有错误或不足请您指出!!!

目录

  • 3.Thread类及常见方法
    • 3.1Thread常见的构造方法
    • 3.2Thread常见的几个属性
  • 4.中断一个线程
    • 4.1自己实现控制线程结束
    • 4.2调用Thread提供的interrupt方法
  • 5 .等待一个线程
  • 6.获取当前线程的引用
  • 7.线程的状态
    • 7.1 new
    • 7.2 terminated
    • 7.3 Runnable
    • 7.4阻塞
    • 7.5查看当前线程的状态

3.Thread类及常见方法

3.1Thread常见的构造方法

在这里插入图片描述
(1)String name,就是在创建线程的时候,给线程起个名字,实际上是否有名字对线程本身没有任何影响,即使你不起名字,线程也会有默认的名字:Thread-0,Thread-1…,只不过起了名字后,当进程执行的过程中,可以通过jconsole / idea看到不同线程的名字,出现问题的时候,更加直观的把问题线程和代码关联起来,方便调试

public class Test1 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(()->{while(true){System.out.println("hello t");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}},"自定义线程");t.start();while(true){System.out.println("hello main");Thread.sleep(1000);}}
}

在这里插入图片描述
(2)对于ThreadGroup,在开发中很少见到,有的时候,希望把多个线程进程分组,分组之后,就可以针对不同的分组进行批量控制
但是这种写法目前在实际开发中更多的是被线程池取代了

3.2Thread常见的几个属性

属性获取方法
IDgetId()
名称getName()
状态getState()
优先级getPriority()
是否后台线程isDaemon()
是否存活isAlive()
是否被中断isInterrupted()

(1)id 这里的id和pcb里面的pid是不一样的,这里的id是jvm自己搞的一套id体系,而我们通过java代码是不能获取到pcb里面的id的

(2)优先级
实际上虽然iava而提供了修改优先级的接口,但是即使你修改了优先级,现象也是不明显的,因为你修改了优先级是一回事,系统调度又是一回事,这里你修改了优先级只能说是一种"建议",具体还是以系统为主

而不仅是在java,即使你通过c去调用系统原生的修改优先级的api,效果也是不明显的,本质上还是因为调度这个事情,操作系统就一堂言了,程序员很难干预到

(3)前台线程和后台线程
对于前台线程,这样的线程不结束的话,java进程是一定不会结束的
对于后台线程,这样的线程即使继续执行,也是无法阻止java进程结束的

前台线程是可以有多个的,但是是有是当最后一个前台线程结束后,进程才算真正结束

在java中,main就是前台线程,而我们自己创建的线程默认也是前台线程,至于其他jvm创建的线程就是后台线程了,比如GC,GC是要周期性持续性的运行的,如果这样的线程设置为前台线程,那么进程就再也结束不了了

在这里插入图片描述
如图所示,main线程和t线程都是前台线程的时候,即使main结束了,进程也没有结束,必须等到t线程结束,进程才结束

在java中,我们可以通过setDaemon来将线程设置为后台线程
在这里插入图片描述
此时由于只有main线程是前台线程,那么一旦前台线程结束后,进程也就结束了

注意:关于线程属性的所有设置都要放在start之前,如果在start之后设置,那就来不及了
在这里插入图片描述

(5)是否存活
指的是在系统中的pcb(线程)是否存活
值得注意的是,线程的生命周期和java中Thread对象的生命周期不一定完全一样的
我们来对比一下下面的两段代码

public class Demo5 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {});t.start();Thread.sleep(1000);}
}

此时由于T线程里面没有做什么事情,因此操作系统内核里面对应的pcb一下子就销毁了,但是由于主线程调用了sleep,在sleep结束之前,Thread对象是不会销毁的

public class Demo5 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}});t.start();t = null;}
}

此时在t线程结束之前,t线程指向的对象就要被GC回收了

因此,对于线程的生命周期和线程对应对象的是生命周期是不一样的,不能说谁长谁短,那么我们就可以利用isAlive来判断系统中的线程是否还存在

4.中断一个线程

中断线程,在java中也只是"提醒、建议"真正要不要终止,还是要线程本身来决定的
即假设t线程正在执行,其他线程只能是提醒一下t线程是否要终止,t收到这样的提醒后,也是靠自己决定要不要终止

4.1自己实现控制线程结束

private static boolean isRunning = true;
public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {while(isRunning){System.out.println("t线程运行");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("t线程结束了");});t.start();//3s后,让t线程结束Thread.sleep(3000);System.out.println("控制t线程结束");isRunning = false;
}

但是假设这里t线程的sleep时间是10s,此时main线程是无法让t线程即使终止掉的

4.2调用Thread提供的interrupt方法

我们刚刚是自己定义的一个boolean变量,实际上Thread里面内置了一个,使用内置的标志位,功能更加强大
在这里插入图片描述
interrupt(): 这是一个实例方法,用于中断线程。当调用某个线程的 interrupt() 方法时,会给该线程设置一个中断标志,表示该线程已被请求中断。如果线程处于阻塞状态(如等待、睡眠或在输入输出操作中被阻塞),它会收到一个 InterruptedException 异常,以此来响应中断请求。在其他情况下,需要检查线程的中断状态,并采取适当的行动来响应中断请求。

interrupted(): 这是一个静态方法,用于检查当前线程是否被中断,并且会清除线程的中断状态。如果调用线程的 interrupted() 方法返回 true,则表示该线程之前被中断过,并且清除了中断状态;如果返回 false,则表示该线程之前未被中断过。通常,这个方法用于检查当前线程是否被中断,并在必要时做出相应的处理。

isInterrupted(): 这是一个实例方法,用于检查线程是否被中断,但不清除中断状态。调用线程的 isInterrupted() 方法返回 true 表示该线程被中断,返回 false 表示未被中断。通常,这个方法用于检查其他线程的中断状态,而不影响当前线程的中断状态。
在这里插入图片描述
当一个线程正在sleep的时候被中断,此时就会抛出InterruptedException异常,即立即唤醒线程,不会再等待了

但是如果我们不采用抛出异常的方法:
在这里插入图片描述
怎么t线程还会继续执行???
实际上是由于sleep,如果调用interrupt方法后,线程没有sleep,确实是直接修改标志位就完了
但是如果正在sleep,那么就会立即唤醒sleep,但sleep在被唤醒的同时,也会清除刚刚的标志位!!!
之所以要清除标志位,实际上也就是要将控制权交给程序员自己,当前代码是要继续执行?还是直接结束,程序员就可以通过代码来决定了
在这里插入图片描述

5 .等待一个线程

在操作系统中.多个线程之间的调度顺序是随机的(抢占式执行),但是我们往往希望线程的执行顺序是稳定的,因此我们希望在随机的体系上,让结果变得不那么随机
具体来说,一个线程数什么时候调度是不确定的,多个线程谁先开始谁先结束是不确定的
我们通过线程的等待,就是要能够确线程结束的先后顺序
在这里插入图片描述
如果不加join方法,那么main线程和t线程谁先结束是不确定的
但是在main线程里面调用t.join,就是要让main线程去等待t线程,也就是t线程结束后,main线程才继续执行下面的逻辑
此时就确保了main线程一定是后结束的那一个线程

注意:此时main线程调用t.join方法就会有几种情况
(1)如果此时t线程已经结束,那么join方法就立即返回,不会阻塞main线程
(2)如果t线程还没结束,那就一直等待到t线程结束
(3)如果t线程还没开始,也是直接返回

实际上join也提供了带超时的版本
在这里插入图片描述
只带一个参数的join,代表等待N ms

带两个参数则精确到毫秒和纳秒

(但是实际上纳秒这个级别的时间,对于主流系统来说,都是太精细了.像windows / linus这样的系统,无法精确到ns级别的时间 甚至到了ms级别都有可能出差错.而且达到ns这种级别的系统开销太大了)

传入的时间则代表最长的等待时间,比如写了10ms,如果10ms还没到,t线程已经结束了,那么就直接返回

如果10ms到了,t线程还没结束,那么就不等了,继续往下走

这种场景应用还是非常广泛的

假如A中的主线程创建t线程,t线程给B发送请求,紧接着A就让主线程t.join等待t线程结束(获取到B响应)

如果B挂了.此时如果是使用死等的策略,就会使A中的主线程卡住了,无法再继续执行后面逻辑了

这种情况就需要制定好超时时间,超过时间就不等了,继续做该做的事情
在这里插入图片描述

6.获取当前线程的引用

public static Thread currentThread();

返回的是当前线程对象的引用

7.线程的状态

我们在上一章节谈到的进程的状态实际上是线程的状态或者叫做pcb的状态
在Java中,对线程的状态大体是分成6中不同的状态

7.1 new

表示Thread对象已经有了,但是还没有start,即操作系统内核的pcb还没创建

7.2 terminated

表示线程已经终止了,即内核中的线程已经销毁了,但是Thread对象还在

7.3 Runnable

分成两种
(1)指的是当前线程正在cpu上执行
(2)指的是这个线程虽然没有在cpu上执行,但随时可以调度到cpu上执行

7.4阻塞

(1)waiting 死等进入的阻塞
(2)timed_waiting 带有超时版本的阻塞(sleep属于其中的一种)
(2)blocked 进行锁竞争时候产生的阻塞(后面会谈到)

7.5查看当前线程的状态

(1)getState
在这里插入图片描述
(2)jconsole
在这里插入图片描述

感谢您的访问!!期待您的关注!!!

在这里插入图片描述

T04BF

🫵 小比特 大梦想

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

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

相关文章

STM32H743VIT6使用STM32CubeMX通过I2S驱动WM8978(2)

接前一篇文章:STM32H743VIT6使用STM32CubeMX通过I2S驱动WM8978(1) 本文参考以下文章及视频: STM32CbueIDE Audio播放音频 WM8978 I2S_stm32 cube配置i2s录音和播放-CSDN博客 STM32第二十二课(I2S,HAL&am…

CLIP大模型图文检索——原理解读及代码实现

一. 核心思想 通过自然语言处理获得的监督信号可用于训练迁移效果出色的视觉模型。本论文的作者团队构建了一个庞大的图像文本配对数据集,其中包含400 million个图片文本的配对。利用最大规模的ViT-large模型,他们提出了CLIP(Contrastive La…

机器学习和深度学习 -- 李宏毅(笔记与个人理解)Day 13

Day13 Error surface is rugged…… Tips for training :Adaptive Learning Rate critical point is not the difficult Root mean Square --used in Adagrad 这里为啥是前面的g的和而不是直接只除以当前呢? 这种方法的目的是防止学习率在训练过程中快速衰减。如果只用当前的…

自然语言处理NLP关键知识点

大家好,在人工智能出现之前,机器智能处理结构化的数据,例如 Excel 里的数据。但是网络中大部分的数据都是非结构化的,例如文章、图片、音频、视频等。在非结构数据中,文本的数量是最多的,他虽然没有图片和视…

信息系统项目管理师——第27章管理科学基础知识

1 最大流量问题[简单] 百度百科:最大流问题,一种组合最优化问题,就是要讨论如何充分利用装置的能力,使得运输的流量最大,以取得最好的效果。 教材P869:在起点和终点之间可能存在多条运输路径,总的最大流量就是求出各…

智能EDM邮件营销推广工具哪个好?

有效且精准的客户沟通已经成为企业成功的关键要素之一,云衔科技以其尖端的智能EDM邮件营销系统解决方案脱颖而出,为全球各行业的企业提供了一个强有力的竞争优势和业绩增长引擎。 云衔科技深谙市场营销的艺术与科学,凭借多年积累的专业技术研…

SPI 机制

一、简述 本文介绍 SPI 机制。 二、什么是 SPI 机制 SPI(Service Provider Interface)机制是 Java 编程语言中的一种机制,用于实现组件之间的解耦和扩展。SPI 允许开发者编写服务接口(Service Interface)&#xff0…

计算机网络 路由器基本配置

一、实验内容 1、按照下表配置好PC机IP地址和路由器端口IP地址 2、配置好路由器特权密文密码“abcd+两位班内序号”和远程登录密码“star” 3、验证测试 a.验证各个接口的IP地址是否正确配置和开启 b.PC1 和 PC2 互ping c.验证PC1通过远程登陆到路由器上&#…

目前深圳嵌入式单片机就业环境如何?

深圳作为中国的科技创新中心之一,嵌入式行业的就业环境相对较好。我这里有一套嵌入式入门教程,不仅包含了详细的视频讲解,项目实战。如果你渴望学习嵌入式,不妨点个关注,给个评论222,私信22,我在…

docker 上达梦导入dump文件报错:本地编码:PG GBK,导入女件编码:PGGB18030

解决方案: 第一步进入达梦数据容器内部 docker exec -it fc316f88caff /bin/bash 第二步:在容器中 /opt/dmdbms/bin目录下 执行命令 cd /opt/dmdbms/bin./dimp USERIDSYSDBA/SYSDBA001 FILE/opt/dmdbms/ZFJG_LJ20240407.dmp SCHEMASZFJG_LJUSERIDSYSD…

linux安装

1、解压vm ware压缩包 2双击安装 3点击自定义硬件 4双击cd/dvd,给虚拟光驱里放虚拟光盘 5记得启动时链接勾上,勾上起点系统时 虚拟光驱才会一起启动 6点击确认即可! 开机 选择第一个 7进入图形化安装界面 8设置时区 9选择硬盘 10网络配置 开启以太网&am…

C语言进阶课程学习记录-数组指针和指针数组分析

C语言进阶课程学习记录-数组指针和指针数组分析 实验-数组指针的大小实验-指针数组小结 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学习记录 实验-数组指针的大小 #include <stdio.h>typedef int(AINT…

【MoS2】应变增强的单层MoS2光电探测器

这篇文章的标题是《Strain-Enhanced Large-Area Monolayer MoS2 Photodetectors》&#xff0c;作者是Borna Radatovic等人&#xff0c;发表在《ACS Applied Materials & Interfaces》期刊的2024年第16卷。文章主要研究了应变增强的大面积单层MoS2光电探测器的性能和应用潜力…

【题目】【信息安全管理与评估】2022年国赛高职组“信息安全管理与评估”赛项样题1

【题目】【信息安全管理与评估】2022年国赛高职组“信息安全管理与评估”赛项样题1 信息安全管理与评估 网络系统管理 网络搭建与应用 云计算 软件测试 移动应用开发 任务书&#xff0c;赛题&#xff0c;解析等资料&#xff0c;知识点培训服务 添加博主wx&#xff1a;liuliu548…

Testng测试框架(3)-数据驱动TestNG@DataProvider

TestNG 是一个强大的 Java 测试框架&#xff0c;它提供了许多高级功能&#xff0c;如参数化测试、依赖注入、分组等。其中&#xff0c;DataProvider 是 TestNG 中一个非常有用的注解&#xff0c;用于为测试方法提供数据。 DataProvider 的作用 使用 DataProvider 注解的方法可…

java数据结构与算法刷题-----LeetCode260. 只出现一次的数字 III

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 与运算取末尾1分组 与运算取末尾1分组 解题思路&#xff1a;时间…

文献速递:深度学习肝脏肿瘤诊断---基于多相增强 CT 和临床数据的恶性肝肿瘤鉴别诊断深度学习

Title 题目 Deep learning for diferential diagnosisof malignant hepatic tumors based on multi-phase contrast-enhanced CT and clinical data 基于多相增强 CT 和临床数据的恶性肝肿瘤鉴别诊断深度学习 Abstract 摘要 Liver cancer remains the leading cause of can…

计算机网络——TCP和UDP协议

目录 前言 前篇 引言 TCP与UDP之间的区别 TCP 三次握手 为什么要三次握手而不是两次握手&#xff1f; 丢包问题与乱序问题的解决 四次挥手 为什么客户端需要等待超时时间&#xff1f; UDP协议 TCP和UDP的主要区别 前言 本博客是博主用于复习计算机网络的博客&…

软件开发安全备受重视,浙江某运营商引入CWASP认证课程,

​浙江省某大型运营商是一家实力雄厚、服务优质的通信运营商&#xff0c;致力于为全省用户提供优质、高效的通信服务。数字时代&#xff0c;该运营商顺应信息能量融合发展趋势&#xff0c;系统打造以5G、算力网络、能力中台为重点的新型信息基础设施&#xff0c;夯实产业转型升…

Redis入门到通关之五大基本数据类型及其使用场景

文章目录 一 什么是NoSQL&#xff1f;二 Redis是什么&#xff1f;三 Redis五大基本类型1 String&#xff08;字符串&#xff09;应用场景 2 List&#xff08;列表&#xff09;应用场景 3 Set&#xff08;集合&#xff09;4 sorted set&#xff08;有序集合&#xff09;应用场景…