Thread的属性和方法及如何中断一个线程

news2024/11/15 8:09:19

文章目录

  • 一. Thread提供的属性和方法
    • 1. Thread常见的构造方法
    • 2. 属性及获取方法
  • 二. 中断(终止)一个线程
    • 1) 自己来实现控制线程结束的例子
    • 2) 使用Thread提供的interrupt和isInterrupted方法来实现控制线程结束

一. Thread提供的属性和方法

1. Thread常见的构造方法

在这里插入图片描述
③ 在创建线程时, 可以给线程起名字, 但是是否取名字, 对于线程本身的运行效果是没有影响的
但是起名字有个好处, java进程运行过程中, 可以通过工具看到每个不同进程的名字, 出现问题时, 更直观的把问题线程和代码关联起来(jconsole / IDEA 调试器, 都能看到线程的名字, 如果没有命名, 也有默认的名字Thread-0, Thread-1…)
在这里插入图片描述

在这里插入图片描述

⑤这个构造方法是把多个线程进行分组, 分组之后, 就可以针对不同的组批量进行控制
但是在开发中很少使用,这种写法目前实际开发中更多的是被线程池取代了

2. 属性及获取方法

在这里插入图片描述
① ID
这里的ID和pcb中的pid是不同的, 是jvm自己搞得一套id体系 (java代码无法获取到pcb中的pid)
④ 优先级
虽然java提供了优先级接口, 实际上就算修改了优先级, 现象也不明显, 因为你修改了优先级是一回事, 系统调度又是另外一回事, 这里修改优先级只能是一个"建议参考", 具体还是人家系统以自身为标准
⑤是否是后台线程
前台线程: 这样的线程如果不结束运行, 此时java进程是一定不会结束的
后台进程: 这样的线程, 即使继续再执行, 也不能阻止java进程结束
前台线程可以有很多个, 多个前台线程, 必须等到最后一个前台线程结束, 整个进程才能结束
在java代码中, main线程, 就是前台线程
程序猿创建出来的线程, 默认情况下都是前台线程
在jcondole中看到的jvm中包含的一些其他的内置线程, 属于后台线程

可以通过setDaemon方法把线程设置为后台线程:
在这里插入图片描述
上述代码, 运行结果为:
在这里插入图片描述
只有当我们写的线程运行完成后进程才会结束, 而main进程执行完start后直接结束了, 对进程没有影响
接下来我们将自定义线程设置成后台进程:
在这里插入图片描述
在start之前加入上述语句, 运行结果为:
在这里插入图片描述
此时, 进程中, 只有main一个前台进程了, 只要main结束了, 整个进程就结束了, main执行完start后立刻就结束了, 此时t还没来得及打印呢, 进程就结束了, 里面的线程自然也就结束了
但是注意:
此处也有一定的概率, 出现thread打印一次, 然后进程结束的情况, 因为线程是抢占式执行的, 调度顺序是不确定的, 就要看main先结束执行还是t先打印

注意: 关于线程的各种属性的设置, 一定要在start前面, 一旦线程已经启动, 再设置就来不及了
在这里插入图片描述
⑥是否存活
指的是系统中的线程PCB是否存在
注意: Thread对象的生命周期和PCB的生命周期是不一定完全一样的
在这里插入图片描述
这个操作, 实在创建Thread实例, Thread对象已经产生, 但是此时内核中的PCB还没有诞生
在这里插入图片描述
这个操作, 才是真正在系统中创建出线程(PCB才真正创建出来并且加入到链表中)
举例1:
在这里插入图片描述
由于thread线程中没有内容, 所以t瞬间就执行结束了, 内核中的线程和pcb就被销毁了
但是在sleep结束之前, thread引用指向的对象, 仍然是存在的, 并没有被GC回收掉
所以此时我们通过isAlive判断一下发现是false:
在这里插入图片描述
举例2:
在这里插入图片描述

线程还没有执行完成, 此时判断线程是否存活:
在这里插入图片描述

二. 中断(终止)一个线程

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

1) 自己来实现控制线程结束的例子

核心思路, 就是让需要终止的线程的入口方法尽快执行结束(跳出循环, 还是尽快return都可以)
我们创建一个boolean类型的成员变量, isRunning, 设置为true, 用来作为循环的条件, 控制进程的结束
等待三秒后, 让isRunning设为false, 此时循环就会结束, 进程结束

public class threadDemo7 {
    private static boolean isRunning = true;
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            while(isRunning){
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println("thread线程已经结束");
        });
        thread.start();
        Thread.sleep(3000);
        System.out.println("控制thread线程结束");
        isRunning = false;
    }
}

这样就实现了在其他线程中控制thread线程的效果

思考:如果我们把变量设置在main方法中, 是否可行?
在这里插入图片描述
发现isRunning标红了
这里的知识点是变量捕获
在Java中,变量捕获(Variable Capturing)通常指的是在匿名内部类或Lambda表达式中,引用外部作用域的局部变量。当在一个匿名内部类或Lambda表达式中引用外部作用域的局部变量时,该局部变量会被捕获并保存下来,以便在内部类或Lambda表达式中访问和使用。
但是捕获的变量必须要满足:
必须是final修饰或"事实"final,即没有被修改


在代码中, 我们后续修改了isRunning的值, 所以在lambda表达式中是无法捕获的

为什么写在类中作为成员变量, 就可以访问呢?
因为此时就不再是变量捕获了, 而是 内部类访问外部类的成员!
lambda表达式本质上就是匿名内部类, 实现了函数式接口
所以内部类访问外部类的变量, 本身就是允许的

但是现在又出现了新的问题, 如果thread线程中sleep10s, 那么我们在main中3s之后, 是无法让thread线程立刻终止的

2) 使用Thread提供的interrupt和isInterrupted方法来实现控制线程结束

isInterrupted方法:
是线程内置的标志位, 刚才我们是自己定义了一个boolean类型的变量, isInterrupted方法其实也是一个boolean变量
true表示线程要终止了
false表示线程要继续执行, 默认为false
在这里插入图片描述
currentThread方法是一个静态方法, 这个方法可以获取到当前线程, 即thread线程
因为在lambda表达式内部, 不能直接用thread线程, 因为还没有创建出来thread对象

interrupt方法:
这个方法, 就相当于是设置boolean值为ture
与自定义变量不同的是, 如果代码中有sleep, 这个方法, 可以让sleep等阻塞方法抛出一个InterruptedException异常, 从而达到唤醒sleep等阻塞方法的目的
在这里插入图片描述
上述代码, 三秒之后, 修改标志位, 并抛出InterruptedException异常, 捕获异常后, 执行catch块中的语句, 继续刨除RuntimeException异常, 线程终止在这里插入图片描述
但是如果我们将catch 块中的语句修改一下, 只打印异常信息在这里插入图片描述
此时运行就会发现:
在这里插入图片描述
修改标志位, 唤醒sleep, 运行catch块中的代码, 此时循环条件已经不再成立, 为什么还会继续打印hello thread呢?
其实, 是sleep在搞鬼
如果代码没有sleep, 确实是直接修改了标志位就完事了, 但是如果有sleep, 并且触发Interrupt的时候, 线程正在sleep, sleep被唤醒的同时, 会清除刚才的标志位(又改回false), 所以循环就继续进行了

那么之所以要将标志位改回来, 就是把是否结束进程的控制权交给程序猿自己, 也就是交给这个线程本身, 别的线程想让你终止, 但是控制权还在你自己的手上:

  1. 如果你不想结束
    那么就可以在catch块中不做任何操作, 此时sleep清除标志位, 代码还会继续运行在这里插入图片描述
  2. 如果想立即结束, 那么就可以直接break
    在这里插入图片描述
  3. 如果想等会再结束, 那么就可以在catch中写写东西, 再break;

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

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

相关文章

戏曲多多 v1.0.4 — 专为老年人打造的戏曲娱乐软件(含经典评书与广场舞)

戏曲多多 TV 是一款专为老年人量身打造的视频娱乐软件,安装在智能电视、智能机顶盒、投影仪等安卓系统设备上后,老年人可以在电视上轻松观看各种戏曲视频。软件涵盖豫剧、京剧、秦腔、越剧、昆曲、淮剧、川剧、黄梅戏等多种戏曲类型。除了戏曲&#xff0…

Java设计模式之原型模式详细讲解和案例示范

引言 在软件设计中,设计模式为我们提供了可复用的解决方案,以应对常见的设计问题。原型模式(Prototype Pattern)是创建型设计模式的一种,它允许通过复制现有对象来创建新对象,而不需要了解创建过程的细节。…

【软件】常用软件教程一:码云(Gitee)使用方法

文章目录 一、简介二、创建远程仓库三、配置SSH公钥四、同步 Gitee 仓库内容到本地五、本地新建文件并同步至 Gitee六、删除远程仓库中的指定文件七、常见代码 一、简介 Git 是一种分布式版本控制系统,用于跟踪和管理代码的变更。它是由 Linus Torvalds 创建的&…

ctfhub-web-SSRF(内网访问-上传文件)

www.ctfhub.com less-1 内网访问 步骤一:开启环境,查看提示 步骤二:输入urlhttp://127.0.0.1/flag.php 得出结果 显示提交成功 less-2 伪协议读取文件 步骤一:开启环境,查看提示 步骤二:输入urlfile://…

英伟达财报引爆AI投资狂潮?华尔街众说纷纭

英伟达,这个名字最近可是火爆了整个科技圈。作为全球最大的GPU供应商,英伟达的每一次动作都牵动着无数投资者的神经。尤其是即将到来的财报发布,更是让市场充满了期待和忐忑。 华尔街聚焦:AI巨头能否持续高增长? 整个…

背完这些软件测试核心面试题,offer轻松拿捏了!

你赞同过 软件测试和开发 相关内容 01、您所熟悉的测试用例设计方法都有哪些?请分别以具体的例子来说明这些方法在测试用例设计工作中的应用。 答:有黑盒和白盒两种测试种类,黑盒有等价类划分法,边界分析法,因果图法…

NVDA财报公布在即,港股围观情绪明显

港股上午盘三大指数低开低走,恒生科技指数一度大跌1.59%,恒指再度失守17800点。盘面上,大型科技股全线下跌令大市承压,百度跌超3%,网易、美团跌超2%,腾讯、快手、阿里巴巴跌超1%;多家房企宣布营…

Git学习(001 git介绍以及安装)

尚硅谷2024最新Git企业实战教程,全方位学习git与gitlab 总时长 5:42:00 共40P 此文章包含第1p-第p4的内容 文章目录 介绍Git介绍GitLab介绍 概述Git安装版本控制工具介绍 介绍 Git介绍 GitLab介绍 相当于中央仓库 概述 Git安装 进入官网(下载当前版本 2.43.0) …

JavaScript ES6+ 新特性

JavaScript ES6 新特性 引言 随着前端技术的不断发展,JavaScript 语言也在不断演进。自 ES6(ES2015)发布以来,JavaScript 引入了许多新的特性和语法,极大地提升了开发者的编程体验和代码的可维护性。本篇文章将详细探…

测试必备--轻松掌握弱网测试技巧

在如今的移动互联网时代,用户对应用的依赖性越来越强。然而,网络环境并非总是理想的,特别是在信号较弱或网络不稳定的情况下,应用的表现尤为重要。你是否曾遇到过这样的情况:在地铁、地下停车场或者偏远地区,网络信号减弱,应用频繁卡顿甚至崩溃?为了确保用户在弱网环境…

JS WebSocket 深度解析

JS WebSocket 深度解析 文章目录 JavaScript WebSocket 深度解析一、WebSocket 是什么二、JS 中如何使用 WebSocket1. 创建 WebSocket 对象2. 连接打开事件3. 监听消息事件4. 监听错误事件5. 关闭连接 三、WebSocket 包含哪些属性或方法 API1. 属性2. 方法 四、扩展与高级技巧1…

微分方程(Blanchard Differential Equations 4th)中文版Section4.5

塔科马海峡大桥 1940年7月1日,耗资600万美元的塔科马海峡大桥正式通车。仅仅四个月后的11月7日,在一场风暴中,这座桥解体并倒塌。这座悬索桥全长超过一英里,曾在它短暂的使用期内因桥面在风中剧烈摆动而被称为“跳跃的格蒂”(Galloping Gertie)。大桥的倒塌不仅成为一场…

KAN+Transformer,一个快速发论文的新创新点!

KAN爆火至今,关于它和Transformer谁更强的问题还没定论,这俩结合的工作效果却愈发出众了,短时间内就有了不少高质量论文发表。 不得不说,这是一种富有创新性的尝试,利用了KAN的灵活性和可解释性,以及Trans…

ocr识别遇到的问题(nested exception is java.lang.UnsatisfiedLinkError)

目录 前言: 问题描述: 解决思路: 解决方法: 总结反思: 前言: 上篇讲过我使用冰蓝的jar包在Java 项目中扫描识别图片中的文字,这篇写更新上线中遇到的问题。 问题描述: 项目打…

c++习题26-大整数加法

目录 一,题目 二,思路 三,代码 一,题目 描述 求两个不超过200位的非负整数的和。 输入 有两行,每行是一个不超过200位的非负整数,可能有多余的前导0。 输出 一行,即相加后的结果。结果里不…

论文合作容易踩坑?学术大咖为你揭秘合作研究中的潜规则

我是娜姐 迪娜学姐 ,一个SCI医学期刊编辑,探索用AI工具提效论文写作和发表。 知乎上的话题,引发大家热议。因为如今合作发表论文在学术圈越来越普遍了。 随着低垂果实都发表了,大家在自己的领域越做越细分,再加上人工智…

WiFi标签注册(电脑版)

安装WiFi-Tool工具 需要windows系统电脑并且有WiFi功能 下载软件安装包:http://a.picksmart.cn:8088/picksmart/app/WiFi-Tool-Setup-V1.0.37.zip 配置操作流程 登录WiFi标签管理系统到设备管理-产品管理,复制“产品ApiKey”参数,打开“WiFi-…

day-42 分割字符频率相等的最少子字符串

思路 动态规划的思想&#xff0c;dp[i]表示从s[0]到s[i]这一子串的最少平衡子串数&#xff0c;当s[i]到s[n-1]是平衡字符串时&#xff0c;dp[i]dp[j-1]1,所以状态转换方程为dp[i]Math.min(dp[j-1]1)&#xff08;1<j<i&#xff09; 解题过程 判断是否为平衡字符串&#x…

《上海服饰》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《上海服饰》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的正规学术期刊。 问&#xff1a;《上海服饰》级别&#xff1f; 答&#xff1a;省级。主管单位&#xff1a;上海世纪出版&#xff08;集团&#xff09;有限公司…

Leetcode 98 验证二叉搜索树 C++实现

Leetcode 98. 验证二叉搜索树 问题&#xff1a;给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身…