线程Thread
文章目录
- 一、概念
- 1、进程
- 2、线程
- 3、CPU与线程的关系
- 4、并行、并发
- 5、线程的生命周期
- 二、创建
- 1、继承Thread
- 2、实现Runnable接口
- 3、实现Callable接口
- 三、API
- 1、获取运行使用的线程
- 2、唯一标识
- 3、线程名
- 4、优先级
- 5、是否处于活动状态
- 6、守护线程
- 7、join
- 1、API
- 2、有无join对比
- 8、yield
- 9、sleep
- 10、线程中断
一、概念
1、进程
- 进程就是正在运行中的程序
2、线程
- 是1个进程(程序内部)的1条执行路径
- 单线程:1个进程中只有1个线程(1条执行路径)
- 多线程:1个进程中包含多个线程(多条执行路径)
- 线程之间堆内存、方法区内存共享;但是栈内存独立,1个线程一个栈
3、CPU与线程的关系
- 单核CPU:不能够做到真正的多线程并发,因为在一个时间单元内,只能执行一个线程的任务,多个线程谁获取时间片运行谁,每个线程获取时间片的概率相等,可能:t1、t2、t2、t2;给人一种多线程并发的感觉:其实是由于CPU的处理速度极快,多个线程之间频繁切换执行,跟人来的感觉是多个事情同时在做
4、并行、并发
- 并行:多核CPU同时执行多个任务。比如:多个人同时做不同的事
- 并发:单核CPU同时执行多个任务。比如:多个人做同一件事
5、线程的生命周期
- 新建状态
- 新建了线程对象,还没调用start方法
- 就绪状态
- 线程调用了start方法等待获取CPU时间片
- 表示当前线程具有抢夺CPU时间片的权力
- 运行状态
- 线程对象开始执行run方法
- run方法的开始执行标志着这个线程进入运行状态,当之前占有的CPU时间片用完之后,会重新回到就绪状态继续抢夺CPU时间片,当再次抢到CPU时间之后,会重新进入run方法接着上一次的代码继续往下执行
- 阻塞状态
- 当一个线程遇到阻塞事件,例如:sleep方法、获取synchronized排他锁失败(因为锁被其它线程所占用)等,此时线程会进入阻塞状态,阻塞状态的线程会放弃之前占有的CPU时间片,之前的时间片没了需要再次回到就绪状态抢夺CPU时间片
- 死亡状态
- run方法执行完毕或者因异常退出了run方法,该线程生命周期结束
二、创建
1、继承Thread
class Thread implements Runnable- 缺点:
- 由于java是单继承的,这导致继承了Thread后就不能在继承其它类了;在实际开发中会经常继承某个超类来复用其中的方法,这导致两者不能同时继承
- 继承线程后重写run方法来定义任务,这又导致我们将任务直接定义在线程上使得线程只能做该任务,无法并发执行其他任务,重用性变差
public class HandleMsg extends Thread{/** 线程标识 */private String threadKey;/** 构造方法用来区分不同线程便于测试 */public HandleMsg(String threadKey){this.threadKey=threadKey;}@Overridepublic void run(){for(int i=0;i<10;i++){System.err.println(threadKey+":run");}}}//匿名内部类lambda
Thread t1=new Thread(()->{for(int i=0;i<10;i++) {System.err.println("t1:run");}
};//创建2个线程对象
HandleMsg h1=new HandleMsg("h1");
HandleMsg h2=new HandleMsg("h2");//启动线程,开始执行实现的run方法
h1.start();
h2.start();
2、实现Runnable接口
- 优点:线程和线程执行的任务分离
public class HandleMsg implements Runnable{/** 线程标识 */private String threadKey;/** 构造方法用来区分不同线程便于测试 */public HandleMsg(String threadKey){this.threadKey=threadKey;}@Overridepublic void run(){for(int i=0;i<10;i++){System.err.println(threadKey+":run");}}}//创建2个任务对象
HandleMsg h1=new HandleMsg("h1");
HandleMsg h2=new HandleMsg("h2");//将任务1交给线程1
Thread t1=new Thread(h1);
//将任务2交给线程2
Thread t2=new Thread(h2);//启动线程,开始执行任务的run方法
t1.start();
t2.start();
3、实现Callable接口
FutureTask implements RunnableFuture,RunnableFuture<V> extends Runnable- 优点
- 线程和线程执行的任务分离
- 有返回值
- 可以声明抛出的异常
//Callable的泛型就是重写的call方法的返回值类型
public class HandleMsg implements Callable<String>{/** 线程标识 */private String threadKey;/** 构造方法用来区分不同线程便于测试 */public HandleMsg(String threadKey){this.threadKey=threadKey;}@Overridepublic String call() throws Exception{for(int i=0;i<10;i++){System.err.println(threadKey+":run");}return threadKey;}}//创建2个任务对象
HandleMsg h1=new HandleMsg("h1");
HandleMsg h2=new HandleMsg("h2");//创建FutureTask类包装任务对象,泛型就是任务类实现Callable的泛型,也就是call方法返回值的类型
FutureTask<String> f1=new FutureTask<>(h1);
FutureTask<String> f2=new FutureTask<>(h2);//将FutureTask对象交给线程
Thread t1=new Thread(f1);
Thread t2=new Thread(f2);//启动线程,开始执行任务的run方法
t1.start();
t2.start();//获取返回值
String result1=f1.get();
String result2=f2.get();
三、API
1、获取运行使用的线程
//在哪个方法执行就获取执行该方法的线程
Thread thread=Thread.currentThread();
2、唯一标识
long getId();
3、线程名
String getName();//线程启动之前可以设置线程名
void setName(String name);
4、优先级
- 线程有10个优先级,用1-10表示,默认为5
int getPriority();//启动之前设置
//线程无法主动获取cpu时间片,唯一可以干涉线程调度工作的方式就是修改线程的优先级,最大程度的改善获取cpu时间片的几率,理论上,线程优先级越高的线程获取cpu时间片的次数越多
void setPriority(int newPriority);
5、是否处于活动状态
boolean isAlive();
6、守护线程
- 守护线程又称为后台线程,默认创建出来的线程都是普通线程或称为前台线程
- 当进程结束时,所有正在运行的守护线程都会被强制中断
- 进程的结束:当一个进程中没有任何前台线程时即结束
- main主线程就是前台线程,不受其他线程影响,分配其他线程后接着干自己的事,其他线程执行的时候,main线程可能已经结束了
//是否为守护线程
boolean isDaemon();//启动之前设置
void setDaemon(boolean on);
7、join
- 作用是:让当前执行的线程陷入等待(内部调用了wait方法)。
- 永久等待:其实现原理是不停的检查当前线程是否存活,该线程的任务执行完毕后就会处于死亡状态,如果存活则说明任务还未执行完毕-继续等待
- 线程启动之后调用
1、API
//等待线程执行完任务后再往下执行,join(0);
void join();//等待线程执行一段时间后再往下执行,无论线程任务是否执行完毕,单位:毫秒
void join(long millis);
2、有无join对比
//1、程序正常运行顺序是不会等待线程任务执行完毕,就会往下执行
Thread t1=new Thread(()->{for(int i=0;i<5;i++){System.err.println(i);}
});
t1.start();System.err.println("next task");// 输出结果
// next task
// 0
// 1
// 2
// 3
// 4//2、调用join
Thread t1=new Thread(()->{for(int i=0;i<5;i++){System.err.println(i);}
});
t1.start();t1.join();System.err.println("next task");// 0
// 1
// 2
// 3
// 4
// next task
8、yield
- 线程让步
- 暂停(不是终止)当前正在执行的线程任务,让其它具有相同优先级或更高优先级的等待的线程执行任务(其它也会包含暂停的线程,所以有可能刚暂停就执行)
- 暂停的线程状态变化:运行状态 -> 就绪状态
- 暂停期间不会释放锁,所以其他线程获取不到锁
9、sleep
- 使线程睡眠
- sleep的睡眠期间不会释放锁,所以其它线程获取不到锁
- 睡眠线程的状态变化:运行状态 -> 阻塞状态 -> 就绪状态
//Thread的静态方法,单位:毫秒
static void sleep(long millis) throws InterruptedException;
- sleep和wait的区别
| sleep | wait |
|---|---|
| 属于Thread类 | 属于Object类 |
| 可以在任何地方使用 | wait、notify、notifyAll 只能在同步方法、同步控制块里面使用 |
| 睡眠期间不会释放锁 | 会释放锁,而且会将当前线程加入到等待队列中 |
| 不需要唤醒 | 可以被notify、notifyAll唤醒 |
10、线程中断
- 只是打断线程的睡眠,不会终止线程的继续执行
//线程是否中断
boolean isInterrupted();//中断线程睡眠
Thread t1=new Thread(()->{System.err.println("run......");try{//睡眠10sThread.sleep(10000L);}catch(InterruptedException e){e.printStackTrace();}System.err.println("end......");
});//启动线程
t1.start();//中断睡眠
//线程不会睡眠10s,而是被中断,抛出InterruptedException,捕获该异常后,继续执行后续的代码
t1.interrupt();System.err.println("next task");// 执行结果
// next task
// run......
// end......
相关文章:
线程Thread
文章目录 一、概念1、进程2、线程3、CPU与线程的关系4、并行、并发5、线程的生命周期 二、创建1、继承Thread2、实现Runnable接口3、实现Callable接口 三、API1、获取运行使用的线程2、唯一标识3、线程名4、优先级5、是否处于活动状态6、守护线程7、join1、API2、有无join对比 …...
如何使用CSS实现一个渐变背景效果?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用CSS实现渐变背景效果⭐ 线性渐变(Linear Gradient)⭐ 径向渐变(Radial Gradient)⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订…...
初始C语言(7)——详细讲解有关初阶指针的内容
系列文章目录 第一章 “C“浒传——初识C语言(1)(更适合初学者体质哦!) 第二章 初始C语言(2)——详细认识分支语句和循环语句以及他们的易错点 第三章 初阶C语言(3)——…...
ArcGIS Pro技术应用(暨基础入门、制图、空间分析、影像分析、三维建模、空间统计分析与建模、python融合、案例应用)
GIS是利用电子计算机及其外部设备,采集、存储、分析和描述整个或部分地球表面与空间信息系统。简单地讲,它是在一定的地域内,将地理空间信息和 一些与该地域地理信息相关的属性信息结合起来,达到对地理和属性信息的综合管理。GIS的…...
RISC-V公测平台发布 · 数据库在RISC-V服务器上的适配评估
前言 上一期讲到YCSB在RISC-V服务器上对MySQL进行性能测试(RISC-V公测平台发布 使用YCSB测试SG2042上的MySQL性能),在这一期文章中,我们继续深入讨论RISC-V数据库的应用。本期就继续利用HS-2平台来测试数据库软件在RISC-V服务器…...
UE5.2 LyraDemo源码阅读笔记(五)输入系统
Lyra里使用了增强输入系统,首先知道增强输入系统里的三个类型配置。 一、Input Actions (IA): 输入操作带来的变量,与玩家的输入组件绑定,回调里驱动玩家行为。 二、InputMappingContext(IMC):…...
线段树详解——影子宽度
OK,今天来讲一讲线段树~~ 线段树是什么线段树的实现线段树的时间复杂度线段树的应用线段树的节点结构其他操作和优化例题——影子宽度输入输出格式输入格式输出格式 输入输出样例输入样例输出样例 例题讲解 线段树是什么 线段树( S e g m e n t Segmen…...
使用R语言绘制折线图
写在前面 昨天我们分享了使用Python绘制折线图的教程,跟着NC学作图 | 使用python绘制折线图,考虑到很多同学基本不使用Python绘图。那么,我们也使用R语言复现此图形。 此外,在前期的教程中,我们基本没有分享过折线图的教程。因此,我们在这里也制作一期关于折线图的教程。…...
无涯教程-Perl - wantarray函数
描述 如果当前正在执行的函数的context正在寻找列表值,则此函数返回true。在标量context中返回false。 语法 以下是此函数的简单语法- wantarray返回值 如果没有context,则此函数返回undef;如果lvalue需要标量,则该函数返回0。 例 以下是显示其基本用法的示例…...
【gitkraken】gitkraken自动更新问题
GitKraken 会自动升级!一旦自动升级,你的 GitKraken 自然就不再是最后一个免费版 6.5.1 了。 在安装 GitKraken 之后,在你的安装目录(C:\Users\<用户名>\AppData\Local\gitkraken)下会有一个名为 Update.exe 的…...
《Java Web程序设计》试卷03
《Java Web程序设计》试卷03 课程编码: 301209 适用专业: 计算机应用(包括JAVA方向) 注 意 事 项 1、首先按要求在试卷标封处填写你所在的系(部)、专业、班级及学号和姓名; 2、仔细阅读各类题目的回答要求,…...
怎么查看小程序中的会员信息
商家通过查看会员信息,可以更好地了解用户,并为他们提供更个性化的服务和推荐。接下来,就将介绍如何查看会员信息。 商家在管理员后台->会员管理处,可以查看到会员列表。支持搜索会员的卡号、手机号和等级。还支持批量删除会员…...
网络安全—黑客—自学笔记
想自学网络安全(黑客技术)首先你得了解什么是网络安全!什么是黑客! 网络安全可以基于攻击和防御视角来分类,我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术,而“蓝队”、“安全运营”、“安全…...
深度解读波卡 2.0:多核、更有韧性、以应用为中心
本文基于 Polkadot 生态研究院整理,有所删节 随着波卡 1.0 的正式实现,波卡于 6 月 28 日至 29 日在哥本哈根举办了年度最重要的会议 Polkadot Decoded 2023,吸引了来自全球的行业专家、开发者和爱好者,共同探讨和分享波卡生态的…...
微服务中间件--Eureka注册中心
Eureka注册中心 a.eureka原理分析b.搭建eureka服务c.服务注册d.服务发现 a.eureka原理分析 1.每个服务启动时,将自动在eureka中注册服务信息 (每个服务每隔30秒发送一次的心跳续约,当某个服务没有发送时,eurekaServer将自动剔除该服务&#x…...
积跬步至千里 || 矩阵可视化
矩阵可视化 矩阵可以很方面地展示事物两两之间的关系,这种关系可以通过矩阵可视化的方式进行简单监控。 定义一个通用类 from matplotlib import pyplot as plt import seaborn as sns import numpy as np import pandas as pdclass matrix_monitor():def __init…...
zookeeper详细介绍
ZooKeeper是一个开源的分布式协调服务,具有以下一些关键特点: 数据模型 ZooKeeper的数据模型采用层次化的多叉树形结构,每个节点称为znode,类似于文件系统中的文件和目录。每个znode可以存储数据和控制信息。一致性保证 ZooKeeper通过ZAB协议,实现分布式环境下数据的强一致性,…...
面板市场趋势分析:价格上涨势头或将减缓 | 百能云芯
8月末,面板价格报价公布,市场研究机构TrendForce指出,电视面板今年以来已经上涨超过30%,虽然下游品牌商对于价格上涨提出了不同声音,但由于面板厂商采取了按需生产的策略,8月仍然出现了3~5%的价格上涨。Tre…...
JVM性能调优
java 如何跨平台,如何一次编译到处执行 是由于java在不同的jvm上编译,jvm在软件层面屏蔽不同操作系统在底层硬件与指令上的区别。 jvm 包括 new 的对象都是放在堆中 栈,给线程单独使用(线程私有),存储一个…...
【全链路追踪】XXL-JOB添加TraceID
文章目录 一、背景调用路径部署环境问题 二、方案三、Demo示例1、MDC2、RequestInterceptor3、HandlerInterceptor4、logback.xml 四、后续改进思路 一、背景 首先这个项目属于小型项目,由于人手以及时间限制,并未引入Skywalking等中间件来做调用链路追…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
