多线程(初阶)
文章目录
- 一.初始线程(Thread)
- 1.1.线程的概念
- 1.2.线程的优势
- 1.2.1.线程比进程更轻量
- 1.2.2.并发编程
- 1.3.线程和进程的区别
- 二.Thread类方法
- 2.1. java 中创建线程的方法
- 2.1.1. 继承Thread,重写run
- 2.1.2. 实现Ruuable接口
- 2.1.3. 使用匿名内部类,继承Thread
- 2.1.4.使用匿名内部类,实现Ruunable
- 2.1.5.使用Lambda表达
- 2.2.Thread 类及常见方法
- 2.2.1. Thread的构造方法
- 2.2.2.Thread的几个常见属性
- 1.前/后台线程
- 2.是否存活
- 3.线程中断
- 2.2.3.等待一个线程join
- 2.2.4. 休眠当前线程
- 2.3. 线程的状态
- 2.3.1.java中线程的状态
- 2.3.2.线程状态和转移
一.初始线程(Thread)
1.1.线程的概念
一个线程就是一个 “执行流”. 每个线程之间都可以按照顺序执行自己的代码. 多个线程之间 “同时” 执行着多份代码. 线程也可以理解成是在进程中独立运行的子任务.
比如,WeChat.exe运行时就有很多的子任务在同时运行。形如,好友视频线程、下载文件线程、传输数据线程等,这些不同的任务或者说功能都可以同时运行,其中每一项任务完全可以理解成是“线程”在工作,传文件、听音乐、发送图片表情等功能都有对应的线程在后台默默地运行.
1.2.线程的优势
1.2.1.线程比进程更轻量
- 创建线程比创建进程更快- 销毁线程比销毁进程更快- 调度线程比调度进程更快
1.2.2.并发编程
如Windows系列,使用多任务操作系统Windows后,可以最大限度地利用CPU的空闲时间来处理其他的任务,比如一边让操作系统处理正在由打印机打印的数据,一边使用Word编辑文档.所以使用多线程技术后,可以在同一时间内运行更多不同种类的任务.
并行 微观上,同一时刻,两个核心上的进程,是同时执行的
并发 微观上,同一个时刻,一个核心上只能运行一个进程,但是它能够快速的进程切换(宏观让人感知不到).
这些都是内核负责处理的,应用程序感知不到,因此往往把并行和并发,统称为并发
单任务和多任务的模型图

在多任务中,CPU可以在任务1和任务2之间来回切换,使任务2不必等5秒后执行,运行效率提升
1.3.线程和进程的区别
- 进程是包含线程的. 每个进程至少有一个线程存在,即主线程.
- 进程和进程之间不共享内存空间. 同一个进程的线程之间共享同一个内存空间(主要指的是内存和文件描述符表).
进程是系统分配资源的最小单位,线程是系统调度的基本单位(如果每个进程有多个线程,每个线程是独立在CPU调度的)
一个线程是通过一个PCB来描述的,所以一个进程里面可能对应一个PCB,也可能是对应多个.
PCB里的状态,上下文,优先级,记账信息,都是每个线程自己的,各自记录各自的,但是同一个进程的PCB之间,pid是一样的,内存指针和文件描述表也是一样的.
线程模型,天然就是资源共享的,多线程争抢同一个资源(同一个变量)非常容易触发竞争
而进程模型,天然就是资源隔离的,不容易触发,进行进程间的通信的时候,多个进程访问同一个资源,可能出现问题
线程是操作系统中的概念. 操作系统内核实现了线程这样的机制, 并且对用户层提供了一些 API 供用户使,而Java 标准库中 Thread 类可以视为是对操作系统提供的 API 进行了进一步的抽象和封装.
二.Thread类方法
先来介绍start,就是调用操作系统的API,通过操作系统内核创建线程的PCB,并且把要执行的指令加给PCB,当PCB被调度到CPU上执行的时候,也就执行到了线程run方法中的代码
Thread t = new MyThread();
t.start();
start是创建了个线程,由新的线程来执行run方法
2.1. java 中创建线程的方法
2.1.1. 继承Thread,重写run

2.1.2. 实现Ruuable接口

2.1.3. 使用匿名内部类,继承Thread

2.1.4.使用匿名内部类,实现Ruunable

2.1.5.使用Lambda表达

2.2.Thread 类及常见方法
2.2.1. Thread的构造方法
| 方法 | 说明 |
|---|---|
| Thread() | 创建线程对象 |
| Thread(Runnable target) | 使用 Runnable 对象创建线程对象 |
| Thread(String name) | 创建线程对象,并命名 |
| Thread(Runnable target, String name) | 使用 Runnable 对象创建线程对象,并命名 |
Thread t1 = new Thread();
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread("名字");
Thread t4 = new Thread(new MyRunnable(), "名字");
2.2.2.Thread的几个常见属性

- ID 是线程的唯一标识,不同线程不会重复
- 名称是各种调试工具用到
- 优先级高的线程理论上来说更容易被调度到
- 关于后台线程,需要记住一点:JVM会在一个进程的所有非后台线程结束后,才会结束运行。
- 是否存活,即简单的理解,为 run 方法是否运行结束了
1.前/后台线程
前台线程,会阻止进程结束,前台线程的工作没完成,进程是结束不了的
后台线程,不会阻止进程结束,后台线程工作没完成,进程也是可以结束的
手动创建的线程,默认都是前台的,包括main默认也是前台的其他的jvm自带的线程都是后台线程
也可以手动的使用setDeamon设置成后台线程(守护线程)
2.是否存活

在调用是start之前,调用isAlive()是false,调用start之后,isAlive就是true,如果内核里线程把run运行完了,此时线程销毁,pcb随之释放,但是Thread t这个对象不一定被释放,此时isAlive是false
public class Thread5 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(()->{while (true){System.out.println("Hellp Thread !");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});System.out.println(t.isAlive());t.start();while (true){Thread.sleep(1000);System.out.println(t.isAlive());}}
}
t的run还没跑,isAlive就是false
t的run还在跑,isAlive就是true
t的run跑完l,isAlivejiusfalse
3.线程中断
中断的意思是,不是让线程立即终止,而是通知,应该要停止,是否真的停止,取决于线程具体的代码写法
-
使用标志位来控制位线程是否要停止
-
使用Thread自带的标志位,来进行判断
| 方法 | 说明 |
|---|---|
| public void interrupt() | 中断对象关联的线程,如果线程正在阻塞,则以异常方式通知,否则设置标志位 |
| public static boolean interrupted() | 判断当前线程的中断标志位是否设置,调用后清除标志位 |
| public boolean isInterrupted() | 判断对象关联的线程的标志位是否设置,调用后不清除标志位 |

intterrupt做两件事
1.把线程内部的标志位(boolean)给设置成true
2.如果线程在进行sleep,就会触发异常,把sleep唤醒,但是sleep在唤醒的时候,会把刚才设置的这个标志,在设置回false

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



2.2.3.等待一个线程join
线程是一个随机调度的过程,等待线程,就是控制两个线程的结束顺序
| 方法 | 说明 |
|---|---|
| public void join() | 等待线程结束 |
| public void join(long millis) | 等待线程结束,最多等 millis 毫秒 |
| public void join(long millis, int nanos) | 同理,但可以更高精度 |

当开始执行的时候,他已经结束,此时join不会阻塞,就会立即返回
2.2.4. 休眠当前线程
让线程休眠,本质上就是让这个线程不参与调度
| 方法 | 说明 |
|---|---|
| public static void sleep(long millis) throws InterruptedException | 休眠当前线程 millis毫秒 |
| public static void sleep(long millis, int nanos) throws InterruptedException | 可以更高精度的休眠 |

一旦线程进入阻塞状态,对应PCB就进入阻塞队列,此时就暂时无法参与调度
PCB是使用链表来组织的(并不具体)实际的情况并不是一个简单的链表,这是一系列以链表为核心的数据结构
2.3. 线程的状态
状态是针对当前的线程调度的情况来描述的,线程是调度的基本单位,状态是线程的属性
2.3.1.java中线程的状态
在java对于线程的状态,进行细化

线程的状态是一个枚举类型Thread.State
public static void main(String[] args) {for (Thread.State state: Thread.State.values()) {System.out.println(state);}}

- NEW: 安排了工作, 还未开始行动
- RUNNABLE: 可工作的. 又可以分成正在工作中和即将开始工作.
- BLOCKED:这几个都表示排队等着其他事情
- WAITING: 这几个都表示排队等着其他事情
- TIMED_WAITING: 这几个都表示排队等着其他事情
- TERMINATED: 工作完成了.
2.3.2.线程状态和转移
先简单了解一下

相关文章:
多线程(初阶)
文章目录一.初始线程(Thread)1.1.线程的概念1.2.线程的优势1.2.1.线程比进程更轻量1.2.2.并发编程1.3.线程和进程的区别二.Thread类方法2.1. java 中创建线程的方法2.1.1. 继承Thread,重写run2.1.2. 实现Ruuable接口2.1.3. 使用匿名内部类,继承Thread2.1.4.使用匿名内部类,实现…...
【Vue从入门到进阶】Node.js安装与配置
✅作者简介:CSDN一位小博主,正在学习前端,欢迎大家一起来交流学习🏆 📃个人主页:白月光777的CSDN博客 🔥系列专栏:Vue从入门到进阶 💬个人格言:但行好事&…...
python 正则使用详解
python 正则使用详解什么是正则在 python 中使用正则一些正则的定义python 正则的方法match 从字符串开头匹配正则返回的结果分析(重要)fullmatch 严格匹配整个字符串search 任意位置开始匹配sub 替换匹配内容subn 以元组方式返回替换结果split 正则切割…...
一个深度学习项目需要什么
DataLoader1.数据预处理在将数据提供给模型之前,DataLoader需要对数据进行预处理。预处理可以包括数据增强、归一化、裁剪、缩放等操作。这些操作可以提高模型的性能和准确度。在处理点云数据时,可以通过最远点下采样到固定的点数。2.读取标签文件我 1 2…...
【Java进阶篇】—— 常用类和基础API
一、String类 1.1 String的特性 java.lang.String 类代表字符串,由final关键字修饰,在赋值后不能改变(常量),不能继承String类String 对象的字符内容是存储在一个字符数组 value[]中的 我们来看一下String在JDK8中的…...
手敲Mybatis(六)-反射工具天花板
历时漫长的岁月,终于鼓起勇气继续研究Mybatis的反射工具类们,简直就是把反射玩出花,但是理解起来还是很有难度的,涉及的内容代码也颇多,所以花费时间也比较浩大,不过当了解套路每个类的功能也好,…...
内含18禁~~关于自学\跳槽\转行做网络安全行业的一些建议
作者:Eason_LYC 悲观者预言失败,十言九中。 乐观者创造奇迹,一次即可。 一个人的价值,在于他所拥有的。所以可以不学无术,但不能一无所有! 技术领域:WEB安全、网络攻防 关注WEB安全、网络攻防。…...
春分策划×运维老王主讲:CMDB数据运营精准化公开课启动报名啦!
『CMDB数据运营精准化』 公开直播课 要来了! 👆扫描海报二维码,预约直播 CMDB似乎是运维中永恒的老话题。 提到CMDB很多人都是又爱又恨,爱的是它给我们提供了一个美好的未来,有了CMDB我们可以解决诸多运维中的难题。…...
制作INCA和CANape通用的A2L
文章目录 前言制作A2LA2ML定义MOD_COMMON定义MOD_PAR定义MEMORY_SEGMENTTransportLayer定义PROTOCOL_LAYERDAQ总结前言 由于INCA和CANape是两个不同的公司对XCP协议的实现,所以A2L中也会有不一样的地方,但是在标定时若每次都用两个A2L,是非常不方便的,本文介绍如何设计A2L…...
Python人脸识别
#头文件:import cv2 as cvimport numpy as npimport osfrom PIL import Imageimport xlsxwriterimport psutilimport time#人脸录入def get_image_name(name):name_map {f.split(.)[1]:int(f.split(.)[0]) for f in os.listdir("./picture")}if not name…...
我用Python写了一个下载网站所有内容的软件,可见即可下,室友表示非常好用
Python 写一个下载网站内容的GUI工具,所有内容都能下载,真的太方便了!前言本次要实现的功能效果展示代码实战获取数据GUI部分最后前言 哈喽大家好,我是轻松。 今天我们分享一个用Python写下载视频弹幕评论的代码。 之前自游写了…...
【M365运维】扩充OneDrive存储空间
【问题】E3,E5等订阅许可下,默认的OneDrive存储空间为 1TB,满了之后该如何扩充?【解决】1.运行Powershell2. 链接到Sharepoint Online: Connect-SPOSerivce -url https://<这里通常是公司名>-admin.sharepoint.com3. 定义三个扩充空间时…...
hashcat(爆破工具,支持GPU,精)
目录 简介 分类 参数 -m hash的类型 -a 攻击方式 掩码 使用方法 字典破解 简介 虽然John the R...
【机器学习】什么是监督学习、半监督学习、无监督学习、自监督学习以及弱监督学习
监督学习(Supervised Learning):利用大量的标注数据来训练模型,模型最终学习到输入与输出标签之间的相关性。半监督学习(Semi- supervised Learning):利用少量有标签数据和大量无标签数据来训练…...
HashiCorp packer 制作AWS AMI镜像示例
准备工作 验证AWS 可以先手动启动一个EC2实例验证自己创建的VPC, subnet, internet gateway 和routetable等, 确保实例创建后不会出现连接不上的情况. 可以按照下面的链接配置避免连接超时 https://docs.aws.amazon.com/zh_cn/AWSEC2/latest/UserGuide/TroubleshootingInstan…...
【java基础】根据泛型动态构造jackson的TypeReference(json反序列化为带泛型的类的对象)
根据泛型动态构造jackson的TypeReference引出问题使用TypeReference反序列化的例子根据泛型动态构造TypeReference带泛型的类如何表示?完成HttpClient的实现引出问题 将json字符串反序列化为带泛型的类的对象怎么操作?怎么根据TypeReference<List<…...
为什么VMware会给我多创建了两个网络呢?Windows和Linux为什么可以彼此ping的通呢
为什么VMware会给我多创建了两个网络呢?Windows和Linux为什么可以彼此ping的通呢 文章目录为什么VMware会给我多创建了两个网络呢?Windows和Linux为什么可以彼此ping的通呢桥接模式ANT模式(VMnet8)仅主机模式(VMnet1&a…...
服务器带宽承载多少人同时访问计算方法-浏览器中查看当前网页所有资源数据大小-客服系统高并发承载人数【唯一客服】...
浏览器中怎么查看当前网页所有资源的数据大小 在开发者工具的“网络”选项卡中,可以看到所有请求和响应的详细信息,包括每个资源的大小。如果需要查看网页所有资源的总大小,可以按照以下步骤操作: 打开要查看的网页。打开开发者工…...
给新手----编译VSOMEIP保姆级别教程
前言:当你学习了SOMEIP理论基础后,一定很希望上手实操一波吧,本文档以SOMEIP协议里比较成熟的VSOMEIP开源框架为例,带你从0到1实现开源框架的下载到上手,坐稳啦,开车!!!&…...
MarkDown设置上下标
上标:$a^{2-5}$ 下标:$a_{n-1}$显示:结果 上标:a2−5a^{2-5}a2−5 下标:an−1a_{n-1}an−1 如果上下标中需要多个显示,需要用{}括起来,否则就像下面一样 上标:$a^2-5$ 下标&…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...
