【Java EE】多线程(二)Thread 类与常用方法

📚博客主页:爱敲代码的小杨.
✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》
❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️
🙏小杨水平有限,欢迎各位大佬指点,相互学习进步!

文章目录
- 0. 前言
- 1. Thread 的常见构造方法
- 2. Thread 类常见属性
- 2.1 ID
- 2.2 名称
- 2.3 状态
- 2.4 优先级
- 2.5 是否后台线程
- 2.6 是否存活
- 2.7 是否被中断
- 3. 启动线程-start()
0. 前言
Thread 类是 JVM 用来创建和管理线程的类,也就是说每个线程都有唯一一个Thread 对象与之关联。
1. Thread 的常见构造方法
| 方法 | 作用 |
|---|---|
| Thread() | 创建线程对象 |
| Thread(String name) | 创建线程对象,并命名 |
| Thread(Runnable target) | 使用 Runnable 对象创建线程对象 |
| Thread(Runnable target, String name) | 使用 Runnable 对象创建线程对象,并命名 |
class MyRunnable implements Runnable{@Overridepublic void run() {}
}public class demo1 {public static void main(String[] args) {Thread t1 = new Thread();System.out.println(t1.getName());Thread t2 = new Thread(new MyRunnable());System.out.println(t2.getName());Thread t3 = new Thread("t3线程");System.out.println(t3.getName());Thread t4 = new Thread(new MyRunnable(), "t4线程");System.out.println(t4.getName());}
}
运行结果:

2. Thread 类常见属性
| 属性 | 方法 |
|---|---|
| ID | getId() |
| 名称 | getName() |
| 状态 | getState() |
| 优先级 | getPriority() |
| 是否后台线程 | isDaemon() |
| 是否存活 | isAlive() |
| 是否被中断 | isInterruupted() |
2.1 ID
ID 是线程的唯⼀标识,不同线程不会重复
public class demo2 {public static void main(String[] args) {Thread t1 = new Thread();System.out.println(t1.getName() + "ID:" + t1.getId());Thread t2 = new Thread("t2线程");System.out.println(t2.getName() + "ID:" + t2.getId());}
}
运行结果:

【注意】:这里的 ID 和 pcb 一一对应,但是这里的 ID 和 系统的中 pcb 上的 ID 是不同的体系(Java代码无法获取到 pcb 中的 ID),JVM 自己搞了一套 ID 体系
比如:我们去上班,在A公司,你的是工号xxxx,后来去到了B公司,你的工号是yyyy,人都是同一个人,在不同的体系中,工号就变了
2.2 名称
public class demo2 {public static void main(String[] args) {Thread t1 = new Thread();System.out.println(t1.getName());Thread t2 = new Thread("t2线程");System.out.println(t2.getName());Thread t3 = new Thread();t3.setName("t3线程"); // 设置线程名称System.out.println(t3.getName());}
}
运行结果:

如果线程没有命名, 默认为 Thread-0, Thread-1...
2.3 状态
后面具体介绍…(下集预告)
2.4 优先级
虽然 Java 提供了优先级接口,实际上就算修改了优先级,现象也不明显,修改了优先级是一回事,系统调度又是另一回事,这里的优先级只能是一个“建议参考”,具体还是系统以自身为准。
本质上还是因为调度这个事情,系统就一言堂了,我们很难干预到。
public class demo9 {public static void main(String[] args) {Thread t1 = new Thread(() -> {while (true) {System.out.println("hello Thread1");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});Thread t2 = new Thread(() -> {while (true) {System.out.println("hello Thread2");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t1.setPriority(Thread.MIN_PRIORITY); // 设置最低优先级t2.setPriority(Thread.MAX_PRIORITY); // 设置最高优先级t1.start();t2.start();}
}
运行结果:


从上图可以看出无论是否设置优先级,运行结果都差不多
2.5 是否后台线程
前台线程: 这种线程如果不运行结束的话, 此时 Java 进程是一定不会结束的
后台线程: 这样的线程, 即使继续在执行, 也不能阻止 Java 进程结束
举例: 酒桌文化
人物: 组局人(前台线程) 小杨(后台线程)
一桌人吃饭, 组局人(前台线程)可以掌握整个宴席(线程)的结束, 当组局人(前台线程)说宴席(线程)结束就结束了, 即使小杨(后台线程)还没有吃完,即使我还没有吃饱,也得撤了(当有多个组局人(多个前台线程)的时候, 当全部的组局人都不吃了, 宴席(线程)就结束了), 如果小杨先吃完,我想先溜(后台线程结束),我溜了对于整个宴席没有任何影响.
当全部的前台线程都结束了, 线程就结束了, 无论后台线程是否执行结束
当后台线程执行结束了, 要等到全部的前台线程结束, 线程才结束
在 Java 代码中, main 线程就是前台线程, 另外创建出来的线程也是前台线程, 可以通过 setDaemon 方法把线程设置为后台线程.
代码:
public class demo10 {public static void main(String[] args) {Thread t1 = new Thread(() -> {for (int i = 0; i < 5; i++) {System.out.println("hello Thread1");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t1.setDaemon(true); // t1线程设置为后台线程t1.start();}
}
运行结果:

【注意】:此处也有一定概率,出现 t1 打印一次,然后结束进程的情况
这种情况就要看是 main 先执行结束,还是 t1 先执行打印1一次(线程之间是抢占式执行的,调度顺序是不确定的)

2.6 是否存活
是否存活: 指的是系统中(pcb) 是否还存在
Thread 对象的生命周期和 pcb 的生命周期是不一定完全一样的

代码:
public class demo11 {public static void main(String[] args) {Thread t1 = new Thread(() -> {try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("线程执行完毕!");});// 判断 t1线程是否存活System.out.println(t1.isAlive());t1.start();System.out.println(t1.isAlive());// 等待线程执行结束try {t1.join();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(t1.isAlive());}
}
运行结果:

2.7 是否被中断
中断线程,在 Java 中,都只是“提醒”,“建议”,真正要不要终止,还得线程本体来进行决定的
t1线程正在执行,其他线程,只能提醒一下 t1 是不是要终止了,t1 收到这样的提醒之后,也还是得自己决定的
常见的方式以下两种:
- 通过共享的标记来进行沟通
- 调用
interrupt()方法来通知
示例一:
public class demo12 {private static boolean isRunning = true;public static void main(String[] args) {Thread t1 = new Thread(() -> {while (isRunning) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("t1线程结束");});t1.start(); // 启动线程// 等待3stry {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}// 3s 后, 主线程修改 isRunning 的值,从而通知 t1 结束System.out.println("控制 t1 线程结束");isRunning = false;}
}
运行结果:

示例二:
public class demo13 {public static void main(String[] args) {Thread t1 = new Thread(() -> {while (!Thread.currentThread().isInterrupted()) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {//throw new RuntimeException(e);//e.printStackTrace();System.out.println("线程即将结束");break; // !!!注意此处的break}}System.out.println("t1线程结束");});t1.start();try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}t1.interrupt();}
}
运行结果:

Thread 收到通知的方式有两种:
- 如果线程因为调⽤
wait/join/sleep等⽅法⽽阻塞挂起,则以InterruptedException异常的形式通知,清除中断标志- 当出现
InterruptedException的时候, 要不要结束线程取决于catch中代码的写法. 可以选择忽略这个异常, 也可以跳出循环结束线程.
- 当出现
- 否则,只是内部的⼀个中断标志被设置,
Thread可以通过Thread.currentThread().isInterrupted()判断指定线程的中断标志被设置,不清除中断标志
这种方式通知收到的更及时,即使线程正在 sleep 也可以马上收到。
3. 启动线程-start()
之前我们已经看到了如何通过重写 run() 方法创建⼀个线程对象,但线程对象被创建出来并不意味着线程就开始运行了。
举例
- 重写
run()方法是提供给线程要做的事情的指令清单- 线程对象可以认为是把 小杨、肯德滑稽叫过来点餐
- 而调用
start()方法,,就是喊一声“去制作吧”,线程才真正独立来执行

调用 start() 方法, 才真的在操作系统的底层创建出一个线程.

相关文章:
【Java EE】多线程(二)Thread 类与常用方法
📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更…...
AGV无人叉车 | 我们为什么要投资“智慧生产”
AGV 作为一种智能工业车辆机器人,无人叉车充分融合叉车技术和AGV技术,近年来在仓储物流领域的应用逐步扩大。在传统叉车厂商、传统AGV厂商、物流集成商及仓储机器人企业等各方力量推动下,无人叉车市场在竞合中快速发展,并促使无人…...
【C++】滑动窗口:将x减到0的最小操作数
1.题目 2.算法思路 这个题目难在要转化一下才能用滑动窗口。 题意是需要在数组的前后两段区间进行解题,但同时对两段区间进行操作是比较困难的,我们可以将中间这段区间只和与nums_sum-x(数组总和-x)进行比较,这样就可…...
运动控制“MC_MoveVelocity“功能块详细应用介绍
1、运动控制单位u/s介绍 运动控制单位[u/s]介绍-CSDN博客文章浏览阅读91次。运动控制很多手册上会写这样的单位,这里的u是英文单词unit的缩写,也就是单位的意思,所以这里的单位不是微米/秒,也不是毫米/秒,这里是一个泛指,当我们的单位选择脉冲时,它就是脉冲/秒,也就是…...
9种单片机常用的软件架构
长文预警,加代码5000多字,写了4个多小时,盘软件架构,这篇文章就够了! 可能很多工程师,工作了很多年,都不会有软件架构的概念。 因为我在做研发工程师的第6年,才开始意识到这个东西,在…...
PyQt5中重要的概念:信号与槽
PyQt中信号与槽概念定义如下(网络上引用的): 信号(signal)和槽(slot)是Qt的核心机制,也是在PyQt编程中对象之间进行通信的机制。在创建事件循环之后,通过建立信号和槽的…...
MacOS快速安装FFmpeg,并使用FFmpeg转换视频
前言:目前正在接入flv视频流,但是没有一个合适的flv视频流地址。网上提供的flv也都不是H264AAC(一种视频和音频编解码器组合),所以想通过fmpeg来将flv文件转换为H264AAC。 一、MacOS环境 博主的MacOS环境(…...
docker部署nginx并配置https
1.准备SSL证书: 生成私钥:运行以下命令生成一个私钥文件。 生成证书请求(CSR):运行以下命令生成证书请求文件。 生成自签名证书:使用以下命令生成自签名证书。 openssl genrsa -out example.com.key 2048 …...
五一小长假,景区智慧公厕发挥了那些作用?
五一小长假已经过去,在旅途中相信大家非常开心,其中也不乏一些细节让你有了更好的体验,而在您享受美景、畅游风光的同时,或许并未留意到那个角落里,默默为您服务的智慧公厕。是的,它们将成为您旅途中不可或…...
Spring - 9 ( 10000 字 Spring 入门级教程 )
一: MyBatis XML 配置文件 Mybatis 的开发有两种方式: 注解XML 我们已经学习了注解的方式, 接下来我们学习 XML 的方式 MyBatis XML 的方式需要以下两步: 配置数据库连接字符串和 MyBatis写持久层代码 1.1 配置连接字符串和 MyBatis 此步骤需要进…...
shpfile转GeoJSON;控制shp转GeoJSON的精度;如何获取GeoJSON;GeoJSON是什么有什么用;GeoJSON结构详解(带数据示例)
目录 一、GeoJSON是什么 二、GeoJSON的结构组成 2.1、点(Point)数据示例 2.2、线(LineString)数据示例 2.3、面(Polygon)数据示例 2.4、特征(Feature)数据示例 2.5、特征集合&…...
没有强有力的科技支撑,就没有保密工作的高质量发展。新修订的《中华人民共和国保守国家秘密法》在总则中新增保密科技创新有关内容包括()
没有强有力的科技支撑,就没有保密工作的高质量发展。新修订的《中华人民共和国保守国家秘密法》在总则中新增保密科技创新有关内容包括() 点击查看答案内容: A.国家鼓励和支持保密科学技术研究和应用B.提升自主创新能力 C.明确依法保护保密领…...
【快速入门】数据库的增删改查与结构讲解
文章的操作都是基于小皮php study的MySQL5.7.26进行演示 what 数据库是能长期存储在计算机内,有组织的,可共享的大量数据的集合。数据库中的数据按照一定的数据模型存储,具有较小的冗余性,较高的独立性和易扩展性,并为…...
使用AIGC生成软件类图表
文章目录 如何使用 AI 生成软件类图表什么是 MermaidMermaid 的图片如何保存?mermaid.liveDraw.io Mermaid可以画什么图?流程图时序图 / 序列图类图状态图甘特图实体关系图 / ER图 如何使用 AI 生成软件类图表 ChatGPT 大语言模型不能直接生成各类图表。…...
机器学习实践:超市商品购买关联规则分析
第2关:动手实现Apriori算法 任务描述 本关任务:编写 Python 代码实现 Apriori 算法。 相关知识 为了完成本关任务,你需要掌握 Apriori 算法流程。 Apriori 算法流程 Apriori 算法的两个输人参数分别是最小支持度和数据集。该算法首先会生成所…...
自动化图像识别:提高效率和准确性的新途径
自动化图像识别是人工智能领域中的一项关键技术,它通过算法自动解析图像内容,为各种应用提供准确的信息。随着技术的不断发展,自动化图像识别在提高效率和准确性方面展现出新的途径。 一、深度学习技术的应用 深度学习是自动化图像识别领域…...
根据最近拒包项目总结,详细讲解Google最新政策(上)
关于占比最多的移动垃圾软件拒审问题 移动垃圾软件(Mobile Unwanted Software)特征表现1> 具有欺骗性,承诺其无法实现的价值主张。2> 诱骗用户进行安装,或搭载在用户安装的其他程序上。3> 不向用户告知其所有主要功能和重要功能。4> 以非预期方式影响用户的系统…...
【Qt之OpenGL】01创建OpenGL窗口
1.创建子类继承QOpenGLWidget 2.重写三个虚函数 /** 设置OpenGL的资源和状态,最先调用且调用一次* brief initializeGL*/ virtual void initializeGL() override; /** 设置OpenGL视口、投影等,当widget调整大小(或首次显示)时调用* brief resizeGL* param w* para…...
如何判断代理IP质量?
由于各种原因(从匿名性和安全性到绕过地理限制),代理 IP 的使用变得越来越普遍。然而,并非所有代理 IP 都是一样的,区分高质量和低质量的代理 IP 对于确保流畅、安全的浏览体验至关重要。以下是评估代理 IP 质量时需要…...
2023-2024年Web3行业报告合集(精选13份)
Web3行业报告(精选13份) 2023-2024年 来源:2023-2024年Web3行业报告合集(精选13份) 【以下是资料目录】 2023Web3产业发展现状分析及国内外落地实践报告 2023模块化区块链承载Web3.0应用的新模式 2023年AI应用需求…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
