多线程1(Thread)

article/2025/6/8 6:13:15

认识线程(Thread)

在进程中,要创建一个进程和销毁一个进程所消耗的硬件和软件资源是巨大的,因此为了优化上述过程,我们引入了“线程”。

线程是系统调度的基本单位。

1)线程和进程的关系

可以认为进程包含线程,一个进程里最少有一个线程,每个线程都可以单独执行一段逻辑,并且可以单独在CPU上调度,因此线程可以叫做“轻量级进程”。

在一个进程中,多个线程共享进程资源,而在后面在这一进程中创建的线程就直接使用进程创建的资源,可以省下申请资源的开销。

2)线程安全问题

当两个线程同时对同一个变量进行修改时,可能会引发线程之间的冲突,这时就会引发线程安全问题(后面详解)。

使用代码实现线程

线程是操作系统中的概念,操作系统中实现了线程这样的机制,因此操作系统对用户层提供了一些API供用户调用,JAVA中就是用Thread这个类进行封装。

Thread类:Thread是JAVA中标准库里的一个类,操作系统本身提供了一些函数进行操作线程,JVM就把这些函数封装成JAVA版本的Thread,这里操作Tread就是操作线程。

五种创建线程的方法:

1)定义一个静态内部类继承自Thread,实现Thread中的Run方法,创建一个这个静态内部类的实例。

public class dome2 {static class MyThread extends Thread{@Overridepublic void run() {System.out.println("hah");}}public static void main(String[] args) {Thread dome = new MyThread();dome.start();}
}

Run方法就是进行执行一段逻辑的入口,run不需要代码显性调用。

注意点1:Start方法就是真正在操作系统中创建一个线程,run方法就是这个线程要执行逻辑的入口,这里如果只是调用run方法就会只执行main这个主线程而不会创建一个新的线程,以一段代码为例:

上述代码调用了start方法,创建了一个新的线程,所以创建的线程和主线程会并发执行,两个打印操作会同时进行。

如果将start去掉,直接调用run,就会只执行主线程,将run中的逻辑执行完才会执行下面,但是run中是死循环,因此只会打印出hah。

注意点2:主线程和新线程之间的执行顺序是由操作系统随机执行的,我们可以通过第三方工具JDK中的jconsole进行观察线程的执行情况。

2)创建一个子类,实现Runnable接口,重写Run方法,搭配Thread进行start

3)创建一个匿名内部类,重写run方法,start方法

4)创建一个runnable的匿名内部类,重写run方法,调用start

5)最简单的写法,在Thread中使用lambda表达式

线程中的几个常见属性

JAVA中对线程的状态进行了进一步扩充(后面细说)

1)后台线程:线程没执行完,进程可以结束(线程不可以结束进程)。

前台线程:线程没执行完,进程不可以结束(线程可以组织进程结束)。

main线程和我们自己创建的线程是前台线程,其他的都是后台线程。

我们可以通过setDaemon设置前台线程为后台线程(必须在线程start前设置),后台线程结束程序就结束了。

(这个程序当主线程运行三次之后结束进程,我们创建的后台线程就会随进程结束而结束)

2)是否存活

当线程没结束时就是true,结束或还没开始执行就是false

启动一个线程

启动一个线程要调用start,调用start才是真正调用系统中创建线程的api,而线程启动后会自动调用run中的内容。

1.调用start是非常快的,不会有任何的阻塞等待。

这里调用完start后就立刻调用下面得sout,打印出main和thread,但是要注意这里先打印出的是main,这是因为调用start后要创建线程。并不是一直是这样的,可能会有例外,这是因为系统调用线程是随机调度的。

2.一个线程只能start一次

一个线程start后就是就绪/阻塞状态,而对于阻塞/就绪状态的线程,就不能start了。

对于一个Thread而言,对应着操作系统中的一个线程。

中断(打断)一个线程

1.通过变量

通过修改线程内的变量进行打断

2.使用isInterrupted和interrupt中断

这里的currentThread是获取到调用此方法对象的引用,isInterrupted是默认false,下面的interrupt是将条件改为true。

注意事项:

如果在线程里加上sleep,再在main中调用interrupt,就会提前唤醒线程,触发异常,同时将isInterrupted重置为false。

总结:1).没使用sleep等阻塞操作时,interrupt会将isInterrupted从false改为true。

2).使用sleep的阻塞操作时,调用interrupt会抛出interruptException异常,将isInterrupted重置为false,同时提前唤醒sleep,但此时我们可以在catch中进行进一步操作,手动决定线程是否结束。

线程的等待

操作系统调用线程是随机调度(抢占式执行),线程等待就是约定好线程的结束顺序。

1.使用join进行等待

这里就是main等待线程t结束,再执行mian中的逻辑,这里的join是死等。

main等待线程t也是可以的,但是要获取的main的引用。

join不一定执行阻塞,当执行join时线程结束,join就不会阻塞等待。

join还有一个重载版本,设置等待的最大时间,最多等待xxx毫秒。


http://www.hkcw.cn/article/UudgJPwZtY.shtml

相关文章

如何进行页面前端监控

🧑‍💻 写在开头 点赞 收藏 学会🤣🤣🤣 前端监控主要分三个方向 前端性能(用户体验优化) 异常监控 业务指标跟 下面我来分别介绍三类指标如何获取 1)前端性能指标: …

【JAVA版】意象CRM客户关系管理系统+uniapp全开源

一.介绍 CRM意象客户关系管理系统,是一个综合性的客户管理平台,旨在帮助企业高效地管理客户信息、商机、合同以及员工业绩。系统通过首页、系统管理、工作流程、审批中心、线索管理、客户管理、商机管理、合同管理、CRM系统、数据统计和系统配置等模块&…

【Python连接数据库基础 04】Django ORM开发指南:模型设计与高效查询完全攻略

Django ORM开发指南:模型设计与高效查询完全攻略 关键词:Django ORM、模型设计、数据库查询优化、Model关系、QuerySet、数据库性能、Python Web开发、ORM最佳实践 摘要:深入解析Django ORM的核心概念和高级用法,从模型设计原则到…

项目计划缺乏风险评估和应对策略,如何完善

项目计划缺乏风险评估和应对策略可通过建立风险识别机制、实施风险定性与定量评估、制定具体应对措施、建立风险监控体系、加强风险意识培训来完善。 特别是实施风险定性与定量评估,这一环节直接决定了风险的处理优先级和资源分配。通过定性评估,我们能明…

java29

1.IO流续续集 序列化流: 上传javabean类后再修改它,会报错 自己定义版本号 方便生产版本号的设置: 版本号要在javabean写完再写 综合练习: 因为不知道写进去多少个对象,因此读的时候不确定读多少次(读一次…

时代星光推出战狼W60智能运载无人机,主要性能超市场同类产品一倍!

在刚刚结束的第九届世界无人机大会上,时代星光科技发布了其全新产品战狼W60智能运载无人机,并展示了基于战狼W60无人机平台的多种应用场景解决方案。据了解,该产品作为一款多旋翼无人机,主要性能参数均远超市场同类产品&#xff0…

Gephi中的Isometric Layout 插件使用应该用什么数据格式

格式如下: 1.导入数据,运行布局算法Isometric Layout ; 2.进入数据面板,选择节点页; 3.已经有一个新列“Computed Z-Level”出现了,但是此时还不是正确的列名,需要改名为[z]; 列…

Mac版本Android Studio配置LeetCode插件

第一步:Android Studio里面找到Settings,找到Plugins,在Marketplace里面搜索LeetCode Editor。 第二步:安装对应插件,并在Tools->LeetCode Plugin页面输入帐号和密码。 理论上,应该就可以使用了。但是&a…

大模型的分词器——算法及示例

文章目录 1. 分词的概述1.1 什么是分词?1.2 分词的重要性1.3 分词方法的演变1.4 分词器的选择 2. Byte-Pair Encoding (BPE)2.1 BPE的概述2.2 BPE的工作原理示例:BPE训练示例:BPE分词伪代码:BPE训练 2.3 BPE的优缺点2.4 BPE在模型…

用户管理页面(解决toggleRowSelection在dialog用不了的隐患,包含el-table的plus版本的组件)

新增/编辑/删除/分配角色&#xff0c;图片上传在此文章分类下另一个文章 1.重点分配角色&#xff1a; <template><!-- 客户资料 --><div class"pageBox"><elPlusTable :tableData"tableData" :tablePage"tablePage" onSi…

构建基于深度学习的人体姿态估计系统 数据预处理到模型训练、评估和部署 _如何利用人体姿态识别估计数据集_数据进行人体姿态估计研究的建议Human3.6M

构建基于深度学习的人体姿态估计系统 数据预处理到模型训练、评估和部署 如何利用人体姿态识别估计数据集_数据进行人体姿态估计研究的建议__ _人体姿态估计数据集:human3.6m w文章内容及代码仅供参考 By. subject: SubjectS1 : Videos Segments Features Depth Scanner Poses…

PyTorch——非线性激活(5)

非线性激活函数的作用是让神经网络能够理解更复杂的模式和规律。如果没有非线性激活函数&#xff0c;神经网络就只能进行简单的加法和乘法运算&#xff0c;没法处理复杂的问题。 非线性变化的目的就是给我们的网络当中引入一些非线性特征 Relu 激活函数 Relu处理图像 # 导入必…

极智项目 | 基于PyQT+Whisper实现的语音识别软件设计

这是一个基于OpenAI的Whisper模型的语音识别应用程序&#xff0c;使用PyQt5构建了简洁直观的用户界面。该应用支持多语言识别&#xff0c;特别优化了中文识别体验。 项目下载&#xff1a;链接 功能特点 简洁现代的深色主题界面支持多语言识别&#xff08;中文、英语、日语等…

【大模型:知识图谱】--1.py2neo连接图数据库neo4j

【图数据库】--Neo4j 安装_neo4j安装-CSDN博客 需要打开图数据库Neo4j&#xff0c; neo4j console 目录 1.图数据库--连接 2.图数据库--操作 2.1.创建节点 2.2.删除节点 2.3.增改属性 2.4.建立关系 2.5.查询节点 2.6.查询关系 3.图数据库--实例 1.图数据库--连接 fr…

关于线缆行业设备数据采集异构问题的解决

通信线缆制造设备 异构设备协议情况 设备具体型号和关键参数数据传输协议拉丝机LW-1-6/560 塑料扁丝拉丝机&#xff08;螺杆120mm&#xff09;进料直径6.5mm→出料2mm 线速245m/min&#xff0c;功率30kWModbus RTU&#xff08;RS485总线&#xff09;对绞机QC-500C 绞弓转速0-…

电力设备故障预测网关技术方案——基于EFISH-SCB-RK3588的国产化替代实践

一、国产化替代战略背景 行业痛点分析 传统x86方案&#xff08;赛扬N100/N150&#xff09;存在单线程性能瓶颈&#xff08;SPECint2006仅15.2分&#xff09;进口芯片供应链风险&#xff08;Intel产品生命周期通常仅3-5年&#xff09;工业现场总线支持不足&#xff08;需外扩CA…

基于SpringBoot的“嗨玩旅游”网站设计与实现(源码+定制+开发)嗨玩旅游平台开发:景点展示与个性化推荐系统(SpringBoot)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

网络安全问题及对策研究

摘 要 网络安全问题一直是近年来社会乃至全世界十分关注的重要性问题&#xff0c;网络关乎着我们的生活&#xff0c;政治&#xff0c;经济等多个方面&#xff0c;致力解决网络安全问题以及给出行之有效的安全策略是网络安全领域的一大目标。 本论文简述了课题的开发背景&…

Modbus转Ethernet IP网关助力罗克韦尔PLC数据交互

在工业自动化领域&#xff0c;Modbus协议是一种广泛应用的串行通信协议&#xff0c;它定义了主站和从站之间的通信规则和数据格式。罗克韦尔PLC是一种可编程的逻辑控制器&#xff0c;通过Modbus协议实现与其他设备之间的数据交互。然而&#xff0c;随着以太网技术的普及和发展&…

SpringBoot 数据库导入导出 Xlsx文件的导入与导出 全量导出 数据库导出表格 数据处理 外部数据

介绍 poi-ooxml 是 Apache POI 项目中的一个库&#xff0c;专门用于处理 Microsoft Office 2007 及以后版本的文件&#xff0c;特别是 Excel 文件&#xff08;.xlsx 格式&#xff09;和 Word 文件&#xff08;.docx 格式&#xff09;。 在管理系统中需要对数据库的数据进行导…