【JavaEE初阶】 Thread类及常见方法

文章目录

  • 🌴Thread类的概念
  • 🌳Thread 的常见构造方法
  • 🎄Thread 的几个常见属性
  • 🍀start()-启动一个线程
  • 🌲中断一个线程
    • 🚩实例一
    • 🚩实例二
    • 🚩实例三
  • 🎍join()-等待一个线程
    • 🚩获取当前线程引用
    • 🚩休眠当前线程
  • ⭕总结

🌴Thread类的概念

Thread 类是 JVM 用来管理线程的一个类,换句话说,每个线程都有一个唯一的 Thread 对象与之关联。

每个执行流,也需要有一个对象来描述,类似下图所示,而 Thread 类的对象就是用来描述一个线程执行流的,JVM 会将这些 Thread 对象组织起来,用于线程调度,线程管理
在这里插入图片描述

🌳Thread 的常见构造方法

在这里插入图片描述
使用如下:

Thread t1 = new Thread();
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread("这是我的名字");
Thread t4 = new Thread(new MyRunnable(), "这是我的名字");

命名操作:

  • 是将你在使用 jconsole 命令观察线程时的看到的线程名改为你自己的重命名

比如有以下程序:

public class Test1 {public static void main(String[] args) {Thread thread = new Thread(()->{while (true) {System.out.println("我的名字叫遇事问春风乄");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}},"遇事问春分乄");thread.start();while (true) {System.out.println("我的名字叫main");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}

当我们用 jconsole 命令进行查看时,结果如下:
在这里插入图片描述
上面就会有我们自己的命名。

这样方便程序猿进行调试

🎄Thread 的几个常见属性

在这里插入图片描述
常见属性说明:

  • ID 是线程的唯一标识,不同线程不会重复

  • 名称是各种调试工具用到

  • 状态表示线程当前所处的一个情况,后面博主会一一介绍

  • 优先级高的线程理论上来说更容易被调度到

  • 关于后台线程,需要记住一点:JVM会在一个进程的所有非后台线程结束后,才会结束运行。

  • 是否存活,即简单的理解,为 run 方法是否运行结束了

  • 线程的中断问题,下面博主会进一步说明

程序举例,有以下程序(Thread.currentThread()表示返回当前线程对象的引用)

public class ThreadDemo {public static void main(String[] args) {Thread thread = new Thread(() -> {for (int i = 0; i < 10; i++) {try {System.out.println(Thread.currentThread().getName() + ": 我还活着");Thread.sleep(1 * 1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName() + ": 我即将死去");},"遇事问春风乄");System.out.println(Thread.currentThread().getName()+ ": ID: " + thread.getId());System.out.println(Thread.currentThread().getName()+ ": 名称: " + thread.getName());System.out.println(Thread.currentThread().getName()+ ": 状态: " + thread.getState());System.out.println(Thread.currentThread().getName()+ ": 优先级: " + thread.getPriority());System.out.println(Thread.currentThread().getName()+ ": 后台线程: " + thread.isDaemon());System.out.println(Thread.currentThread().getName()+ ": 活着: " + thread.isAlive());System.out.println(Thread.currentThread().getName()+ ": 被中断: " + thread.isInterrupted());thread.start();while (thread.isAlive()) {}System.out.println(Thread.currentThread().getName()+ ": 状态: " + thread.getState());}
}

运行结果如下:
在这里插入图片描述

🍀start()-启动一个线程

之前我们已经看到了如何通过覆写 run 方法创建一个线程对象,但线程对象被创建出来并不意味着线程就开始运行了。

  • 覆写 run 方法是提供给线程要做的事情的指令清单

  • 线程对象可以认为是张三把 李四、王五叫过来了

  • 而调用 start() 方法,就是张三喊一声:”行动起来!“,线程才真正独立去执行了
    在这里插入图片描述
    调用 start 方法, 才真的在操作系统的底层创建出一个线程

🌲中断一个线程

李四一旦进到工作状态,他就会按照行动指南上的步骤去进行工作,不完成是不会结束的。但有时我们需要增加一些机制,例如老板突然来电话了,说转账的对方是个骗子,需要赶紧停止转账,那张三该如何通知李四停止呢?这就涉及到我们的停止线程的方式了。

目前常见的有以下两种方式:

  1. 通过共享的标记来进行沟通

  2. 调用 interrupt() 方法来通知

🚩实例一

使用自定义的变量来作为标志位.

  • 需要给标志位上加 volatile 关键字(这个关键字的功能后面介绍,就暂时理解为一个共享的变量)

比如有以下程序:

public class ThreadDemo1 {private static class MyRunnable implements Runnable {public volatile boolean isQuit = false;@Overridepublic void run() {while (!isQuit) {System.out.println(Thread.currentThread().getName()+ ": 别管我,我忙着转账呢!");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+ ": 啊!险些误了大事");System.out.println("停止转账");}}public static void main(String[] args) throws InterruptedException {MyRunnable target = new MyRunnable();Thread thread = new Thread(target, "李四");System.out.println(Thread.currentThread().getName()+ ": 让李四开始转账。");thread.start();Thread.sleep(10 * 1000);System.out.println(Thread.currentThread().getName()+ ": 老板来电话了,得赶紧通知李四对方是个骗子!");target.isQuit = true;}
}

运行结果如下:
在这里插入图片描述
我们可以里看到当李四收到了受骗的通知后,停止了转账行为

🚩实例二

使用Thread.interrupted() 或者 Thread.currentThread().isInterrupted()代替自定义标志位.

Thread 内部包含了一个 boolean 类型的变量作为线程是否被中断的标记

在这里插入图片描述
比如以下程序:

public class ThreadDemo2 {private static class MyRunnable implements Runnable {@Overridepublic void run() {// 两种方法均可以while (!Thread.interrupted()) {//while (!Thread.currentThread().isInterrupted()) {System.out.println(Thread.currentThread().getName()+ ": 别管我,我忙着转账呢!");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();System.out.println(Thread.currentThread().getName()+ ": 有内鬼,终止交易!");// 注意此处的 breakbreak;}}System.out.println(Thread.currentThread().getName()+ ": 啊!险些误了大事");}}public static void main(String[] args) throws InterruptedException {MyRunnable target = new MyRunnable();Thread thread = new Thread(target, "李四");System.out.println(Thread.currentThread().getName()+ ": 让李四开始转账。");thread.start();Thread.sleep(10 * 1000);System.out.println(Thread.currentThread().getName()+ ": 老板来电话了,得赶紧通知李四对方是个骗子!");thread.interrupt();}
}

运行结果如下:
在这里插入图片描述
hread 收到通知的方式有两种:

  1. 如果线程因为调用 wait/join/sleep 等方法而阻塞挂起,则以InterruptedException 异常的形式通知,清除中断标志当出现InterruptedException 的时候, 要不要结束线程取决于 catch 中代码的写法. 可以选择忽略这个异常, 也可以跳出循环结束线程.

上述代码中,博主在catch里加了break,所以停止了交易,当我们去掉break时,效果如下:
在这里插入图片描述
我们再来看一下运行结果:
在这里插入图片描述
我们发现我们如果不去结束循环,该线程会在抛出异常后继续运行。

这就将主动权交到了我们程序员自己的手上,你通知归通知,停不停止是我自己的决定的

  1. 否则,只是内部的一个中断标志被设置,thread 可以通过
  • Thread.interrupted() 判断当前线程的中断标志被设置,清除中断标志

  • Thread.currentThread().isInterrupted() 判断指定线程的中断标志被设置,不清除中断标志

这种方式通知收到的更及时,即使线程正在 sleep 也可以马上收到

🚩实例三

观察标志位是否清除

标志位是否清除, 就类似于一个开关.

  • Thread.interrupted() 相当于按下开关, 开关自动弹起来了. 这个称为 “清除标志位”
  • Thread.currentThread().isInterrupted() 相当于按下开关之后, 开关弹不起来, 这个称为 “不清除标志位”
  • 使用 Thread.interrupted() , 线程中断会清除标志位
    代码如下:
public class ThreadDemo3 {private static class MyRunnable implements Runnable {@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println(Thread.interrupted());}}}public static void main(String[] args) throws InterruptedException {MyRunnable target = new MyRunnable();Thread thread = new Thread(target, "李四");thread.start();thread.interrupt();}
}

运行结果为:
在这里插入图片描述

  • 使用 Thread.currentThread().isInterrupted() , 线程中断标记位不会清除.
    代码如下:
public class ThreadDemo4 {private static class MyRunnable implements Runnable {@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().isInterrupted());}}}public static void main(String[] args) throws InterruptedException {MyRunnable target = new MyRunnable();Thread thread = new Thread(target, "李四");thread.start();thread.interrupt();}
}

运行结果如下:
在这里插入图片描述

🎍join()-等待一个线程

有时,我们需要等待一个线程完成它的工作后,才能进行自己的下一步工作。

例如,张三只有等李四转账成功,才决定是否存钱,这时我们需要一个方法明确等待线程的结束

代码示例如下:

public class ThreadDemo5 {public static void main(String[] args) throws InterruptedException {Runnable target = () -> {for (int i = 0; i < 3; i++) {try {System.out.println(Thread.currentThread().getName()+ ": 我还在工作!");Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName() + ": 我结束了!");};Thread thread1 = new Thread(target, "李四");Thread thread2 = new Thread(target, "王五");System.out.println("先让李四开始工作");thread1.start();thread1.join();System.out.println("李四工作结束了,让王五开始工作");thread2.start();thread2.join();System.out.println("王五工作结束了");}
}

运行结果为:
在这里插入图片描述
上述只是一个简单的应用,join()还提供了其他方法
在这里插入图片描述
关于 join 还有一些细节内容,博主会在后面的章节进行讲述

🚩获取当前线程引用

这个方法我们以及非常熟悉了,前面都已经使用过了,就不做过多赘述了

public static Thread currentThread();返回当前线程对象的引用

🚩休眠当前线程

也是我们比较熟悉一组方法,有一点要记得,因为线程的调度是不可控的,所以,这个方法只能保证实际休眠时间是大于等于参数设置的休眠时间的。

public static void sleep(long millis) throws InterruptedException休眠当前线程 millis毫秒
public static void sleep(long millis, int nanos) throwsInterruptedException可以更高精度的休眠

关于 sleep,以后博主还会有一些知识会给大家补充的。

⭕总结

关于《【JavaEE初阶】 Thread类及常见方法》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下!

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

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

相关文章

想要开发一款游戏, 需要注意什么?

开发一款游戏是一个复杂而令人兴奋的过程。游戏开发是指创建、设计、制作和发布电子游戏的过程。它涵盖了从最初的概念和创意阶段到最终的游戏发布和维护阶段的各个方面。 以下是一些需要注意的关键事项&#xff1a; 游戏概念和目标&#xff1a; 确定游戏开发的核心概念和目标…

【SpringBoot】| Thymeleaf 模板引擎

目录 Thymeleaf 模板引擎 1. 第一个例子 2. 表达式 ①标准变量表达式 ②选择变量表达式&#xff08;星号变量表达式&#xff09; ③链接表达式&#xff08;URL表达式&#xff09; 3. Thymeleaf的属性 ①th:action ②th:method ③th:href ④th:src ⑤th:text ⑥th:…

TCP相关面试题

TCP相关面试题 题目1 介绍一下TCP三次握手的过程 介绍TCP三次握手应该从3个方面进行回答&#xff0c;分别是数据包名称&#xff0c;客户端与服务端的状态变化&#xff0c;数据包的序号变化。而不能只是简单回答发送的数据包名称。 TCP三次握手的过程如下&#xff1a; 从数据…

NSSCTF [BJDCTF 2020]easy_md5 md5实现sql

开局一个框 啥都没有用 然后我们进行抓包 发现存在提示 这里是一个sql语句 看到了 是md5加密后的 这里也是看了wp 才知道特殊MD5 可以被识别为 注入的万能钥匙 ffifdyopmd5 加密后是 276F722736C95D99E921722CF9ED621C转变为字符串 后是 or6 乱码这里就可以实现 注入 所…

定时任务详解

1、定时任务 在公司做项目时&#xff0c;经常遇到要用到定时任务的事情&#xff0c;但是对定时任务不熟练的时候会出现重复任务的情况&#xff0c;不深入&#xff0c;这次将定时任务好好学习分析一下 定时任务的原理 假如我将一个现场通过不断轮询的方式去判断&#xff0c;就…

理解一致性哈希算法

摘要&#xff1a;一致性哈希是什么&#xff0c;使用场景&#xff0c;解决了什么问题&#xff1f; 本文分享自华为云社区《16 张图解 &#xff5c; 一致性哈希算法》&#xff0c;作者&#xff1a;小林coding。 如何分配请求&#xff1f; 大多数网站背后肯定不是只有一台服务器…

文件格式转换

把我的悲惨故事说给大家乐呵乐呵&#xff1a;老板让运营把一些数据以json格式给我&#xff0c;当我看到运营在石墨文档上编辑的时候我人都傻了&#xff0c;我理解运营的艰难&#xff0c;可我也是真的难啊&#xff0c;在石墨文档编辑的眼花缭乱的&#xff0c;很多属性都错乱了(诸…

[SWPUCTF 2021 新生赛]sql - 联合注入

这题可以参考文章&#xff1a;[SWPUCTF 2021 新生赛]easy_sql - 联合注入||报错注入||sqlmap 这题相比于参考文章的题目多了waf过滤 首先&#xff0c;仍然是网站标题提示参数是wllm 1、fuzz看哪些关键字被过滤&#xff1a;空格、substr、被过滤 2、?wllm-1/**/union/**/selec…

微信小程序 movable-area 区域拖动动态组件演示

movable-area 组件在小程序中的作用是用于创建一个可移动的区域&#xff0c;可以在该区域内拖动视图或内容。这个组件常用于实现可拖动的容器或可滑动的列表等交互效果。 使用 movable-area 组件可以对其内部的 movable-view 组件进行拖动操作&#xff0c;可以通过设置不同的属…

消息驱动 —— SpringCloud Stream

Stream 简介 Spring Cloud Stream 是用于构建消息驱动的微服务应用程序的框架&#xff0c;提供了多种中间件的合理配置 Spring Cloud Stream 包含以下核心概念&#xff1a; Destination Binders&#xff1a;目标绑定器&#xff0c;目标指的是 Kafka 或者 RabbitMQ&#xff0…

信息增益,经验熵和经验条件熵——决策树

目录 1.经验熵 2.经验条件熵 3.信息增益 4.增益比率 5.例子1 6.例子2 在决策树模型中&#xff0c;我们会考虑应该选择哪一个特征作为根节点最好&#xff0c;这里就用到了信息增益 通俗上讲&#xff0c;信息增益就是在做出判断时&#xff0c;该信息对你影响程度的大小。比…

抖音seo源代码开源部署----基于开放平台SaaS服务

抖音SEO搜索是什么&#xff1f; 抖音SEO搜索是指在抖音平台上进行搜索引擎优化&#xff08;Search Engine Optimization&#xff09;的一种技术手段。 通过优化抖音账号、发布内容和关键词等&#xff0c;提高抖音视频在搜索结果中的排名&#xff0c;从而增加视频曝光量和用户点…

ValueError: high is out of bounds for int32 报错

问题描述&#xff1a; 笔者在Windows 64位平台跑一个在Ubuntu上运行正常的程序时&#xff0c;出现了以下报错&#xff1a; 具体为&#xff1a; seed np.random.randint(0, 2 ** 32) # make a seed with numpy generatorFile "mtrand.pyx", line 763, in numpy.ra…

Moonbeam Ignite强势回归

参与Moonbeam上最新的流动性计划 还记得新一轮的流动性激励计划吗&#xff1f;Moonbeam Ignite社区活动带着超过300万枚GLMR奖励来啦&#xff01;体验新项目&#xff0c;顺便薅一把GLMR羊毛。 本次Moonbeam Ignite活动的参与项目均为第二批Moonbeam生态系统Grant资助提案中获…

BaseQuickAdapter触底刷新实现

触底刷新实现 使用BaseQuickAdapter&#xff0c;在适配器中实现 LoadMoreModule即可&#xff0c;如下加上即可&#xff0c;无需多写代码 以下为分页实现&#xff1a; 视图中 // 获取加载更多模块loadMoreModule blogAdapter.getLoadMoreModule();loadMoreModule.setOnLoadMo…

无线振弦采集仪在岩土工程中如何远程监测和远程维护

无线振弦采集仪在岩土工程中如何远程监测和远程维护 随着岩土工程施工的不断发展和科技水平的不断提高&#xff0c;远程监测和远程维护设备也得到了广泛关注和应用。无线振弦采集仪是一种广泛应用于岩土工程中的测量仪器&#xff0c;在现代化施工中扮演着重要的角色。本文将就…

2023学生近视了用什么台灯好呢?好用预防近视的护眼台灯推荐

自从护眼台灯能够帮助孩子在写作业时能够缓解视觉疲劳以来&#xff0c;许多家长已经给孩子安排上来护眼台灯&#xff0c;护眼台灯能够提供良好的照明环境&#xff0c;并且能够让我们专心学习提高工作效率。但由于护眼台灯含有独家的黑科技技术&#xff0c;价格始终居高不下&…

【微信小程序开发】一文学会使用CSS样式布局与美化

引言 在微信小程序开发中&#xff0c;CSS样式布局和美化是非常重要的一部分&#xff0c;它能够为小程序增添美感&#xff0c;提升用户体验。本文将介绍如何学习使用CSS进行样式布局和美化&#xff0c;同时给出代码示例&#xff0c;帮助开发者更好地掌握这一技巧。 一、CSS样式布…

ssm+vue的公司人力资源管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的公司人力资源管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结…

【Overload游戏引擎分析】画场景栅格的Shader分析

Overload引擎地址&#xff1a; GitHub - adriengivry/Overload: 3D Game engine with editor 一、栅格绘制基本原理 Overload Editor启动之后&#xff0c;场景视图中有栅格线&#xff0c;这个在很多软件中都有。刚开始我猜测它应该是通过绘制线实现的。阅读代码发现&#xff0…