多线程Thread常用方法和状态
Thread类 及常见方法
1、常见构造方法
| 方法 | 说明 |
|---|---|
| Thread() | 创建线程对象 |
| Thread(Runnable target) | 使用 Runnable 对象创建线程对象 |
| Thread(String name) | 创建线程对象,并命名 |
| Thread(Runnable target, String name) | 使用 Runnable 对象创建线程对象,并命名 |
| Thread(ThreadGroup group, | 线程可以被用来分组管理,分好的组即为线程组(了解即可,不详细讲) |
上篇文章基本上都讲解过了,我们这里只讲解两个Thread(String name)以及Thread(Runnable target, String name) 来讲解
这两个方法都可以在创建线程的时候,给线程起给名字(这个名字运行重复),目的就是为了方便程序员调试。一旦出问题,就更方便找到对应的代码。
如果不自定义名字,JVM 就会按照thread-0 ,thread-1…来命名
1.1Thread(Runnable target, String name)
public class Main {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (true) {try {Thread.sleep(3000);System.out.println("hello");} catch (InterruptedException e) {throw new RuntimeException(e);}}}, "Thread线程自定义名字");thread.start();}}
通过jconsole来查看验证:

2、Thread 的几个常见属性
| 属性 | 获取方法 |
|---|---|
| ID | getId() |
| 名称 | getName() |
| 状态 | getState() |
| 优先级 | getPriority() |
| 是否是后台线程 | isDaemon() |
| 是否存活 | isAlive() |
| 是否被中断 | isInterrupted() |
ID:
Java中给Thread对象安排的身份标识;和操作系统内核中的PCB的pid以及和操作系统提供的线程线程API中的线程id都不是一回事。
名称:
就是前面构造方法中我们自己自定义的名称
状态:
下面单独讲。
优先级:
获取线程的优先级
后台线程:
默认创建的是前台线程,后台线程指的是当所有(main线程)前台线程执行完毕以后,不管后台线程有没有执行完,直接退出进程。前台进程就不会。
是否存活:
判定内核的线程在不在!
Thread对象虽然和内核中的线程是一一对应的,但是生命周期并非完全相同。
Thread t = new Thread();这样虽然Thread对象出来了,内核里的线程还不一定有;调用start方法,内核线程才会有,当内核里的线程执行完了(run方法运行完了),内核的线程就销毁了,但是Thread对象还在。
[经典的面试题]
调用 start 才会真正创建线程!! 不调用 start 没创建线程 (在内核里创建 PCB)
注意理解, start 和 run 的区别!! **
直接调用 run 并没有创建线程,只是在原来的线程中运行的代码
调用 start,则是创建了线程**,在新线程中执行代码(和原来的线程是并发的)
线程的中断:
run方法执行完了,线程就结束了.有没有办法,让线程,提前一点结束呢??
通过线程中断的方式来进行;
本质:让run方法尽快结束,而不是run执行一半强制结束。
目前常见的有以下两种方式:
通过共享的标记来进行沟通
调用 interrupt() 方法来通知
1、通过共享的标记来进行沟通:

2、使用标准库里面自带的一个标志位
使用 Thread.interrupted() 或者 Thread.currentThread().isInterrupted() 代替自定义标志位
| 方法 | 说明 |
|---|---|
| public static boolean interrupted() | 判断当前线程的中断标志位是否设置,调用后清除标志位 |
| public boolean isInterrupted() | 判断对象关联的线程的标志位是否设置,调用后不清除标志位 |
使用 thread 对象的 interrupt() 方法通知线程结束.
在主线程,通过thread.interrupt()设置标志位为true!
2.1使用Thread.currentThread().isInterrupted()判断当前线程的中断标志被设置

启动时我们发现:

报错了,并且线程也没有中断,为什么?
2.1.1、interrupt方法的行为,有两种情况:
1、t线程在运行状态:
调用t.interrupt()会设置标志位为true。结果**!**后正常中断。

。
2、线程在阻塞状态( wait/join/sleep 等方法而阻塞挂起)
不会设置标志位,而是触发一个InterruptedException 异常的形式通
知,清除中断标志,并且提前将阻塞状态唤醒!
前面有讲到线程中断的本质是:本质:让run方法尽快结束,而不是run执行一半强制结束。
下面就可以体现出来,当遇到InterruptedException 异常的形式通知时候。会触发这个异常:

具体的如何处理,就在于补抓到异常以后用户的代码是如何写
①立即结束进程:

②不理会:

③稍后处理:

2.2使用Thread.interrupted() 判断当前线程的中断标志被设置

当这个使用这个作为标志位时候调用thread.interrupt()时候问题同上;
他们两个方法的不同之处就在于:

什么叫做清楚标志位,什么叫做不清除?
清除标志位:
public class ThreadDemo {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(()-> {for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().interrupted());}});thread.start();thread.interrupt();}
}
打印结果:
true // 只有一开始是 true,后边都是 false,因为标志位被清
false
false
false
false
false
false
false
false
false
不清除标志位:
public class ThreadDemo {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(()-> {for (int i = 0; i < 10; i++) {System.out.println(Thread.interrupted());}});thread.start();thread.interrupt();}
}
true // 全部是 true,因为标志位没有被清
true
true
true
true
true
true
true
true
true
3、等待一个线程-join()
join()可以控制线程之间的结束顺序
线程之间的调度顺序,是不确定的!!可以通过一些特殊操作,来对线程的执行顺序,做出干预其中 join 就是一个办法,控制线程之间的结束顺序!!
Tips:Java 中的多线程方法,只要是这个方法会阻塞,都可能会抛出InterrupttedException 异常!!
效果:在main中调用t.join效果就是让main线程阻塞等待,等到t执行完了,main才继续执行!!
public class ThreadDemo {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(()-> {for(int i = 0; i < 10; i++) {}});t.start();t.join();}
}
当调用t.join()时候,main线程进入阻塞,不参与CPU的调度。
| 方法 | 说明 |
|---|---|
| public void join() | 等待线程结束 |
| public void join(long millis) | 等待线程结束,最多等 millis 毫秒 |
| public void join(long millis, int nanos) | 等待线程结束,最多等 millis 毫秒,但可以更高精度 |
实际应用:
服务器开发经常要处理客户端的请求,根据请求计算生成响应 就需要用到“等待时间”称为“超时时间“客户端发了请求过来,等待响应,这个等待就不能无限的等 可以根据需要,约定 1000ms 500ms如果时间之内响应没有回来,客户端直接提示“等待超时
4、获取当前线程引用
public static Thread currentThread() :返回当前线程对象的引用
5、休眠当前线程
注意:由于线程的调度是不可控制的,所以,这个方法只能保证实际休眠时间是大于等于参数设置的休眠时间的
| 方法 | 说明 |
|---|---|
| public static void sleep(long millis) throws InterruptedException | 休眠当前线程 millis毫秒 |
| public static void sleep(long millis, int nanos) throws | 可以更高精度的休眠 |
sleep:指定休眠的之间(阻塞一会会)
如何更加好的理解sleep?
操作系统管理这么多个PCB的时候是有多个链表的,调用了sleep,则当前调用sleep的PCB就会被移动到另外的“阻塞队列”中。如图:


通过上诉案例我们也能够清楚的认识到,使用sleep(1000)的话,实际阻塞时间是大于等于1s的,这完全取决于调度了。
状态-Thread常见属性
这里特指Java中的对Thread的状态规则
NEW:Thread对象创建出来了,但是内核的PCB还没创建。
TERMINATED:内核的PCB销毁了,但是Thread对象还在。
RUNNABLE:就绪状态(正在CPU上运行 + 在就绪队列中排队)
TIMED_WAITING:按照一定的时间,进行阻塞。
WAITING:特殊的阻塞状态(调用wait)
BLOCKED:等待锁的时候竟然的阻塞状态
一个线程状态之间的变化如下图:

相关文章:
多线程Thread常用方法和状态
Thread类 及常见方法 1、常见构造方法 方法说明Thread()创建线程对象Thread(Runnable target)使用 Runnable 对象创建线程对象Thread(String name)创建线程对象,并命名Thread(Runnable target, String name)使用 Runnable 对象创建线程对象,并命名Thre…...
Codeforces Round #836 (Div. 2)
A SSeeeeiinngg DDoouubbllee 题意:告诉你一个字符串。若该串上每一位上的字母都可以出现两次,求回文串 思路:正向再反向输出s即可 #include <bits/stdc.h> #define lowbit(x) x&(-x) #define ios cin.sync_with_stdio(false)…...
Python学习之项目实践: 写一个MP3播放器
下面呢,是一个 Python MP3 播放器,它使用 pygame 模块来实现音乐播放功能: import pygame class MP3Player: """ MP3 播放器类 """ def __init__(self): pygame.mixer.init() def play(self, file_path): &quo…...
RocketMQTemplate 实现消息发送
代码托管于gitee:easy-rocketmq 文章目录一、前置工作二、消费者三、生产者1. 普通消息2. 过滤消息3. 同步消息4. 延时消息5. 批量消息6. 异步消息7. 单向消息8. 顺序消息9. 事务消息概要Demo源码解读一、前置工作 1、导入依赖 <dependency><groupId>…...
教师干货丨这5款微课必备提效神器,我要告诉全世界!
微课是一种短小精悍的视频教学形式,其设计和演示因特别简洁明了而被定义为“小而美”。由于只在几分钟时间内向学生传授所需知识,微课为学习者提供更多的选择机会和时间节约的便利,而这种趋势已经逐渐在新的社交媒体环境中显现出来。在制作微…...
timm使用swin-transformer
1.安装 pip install timm2.timm中有多少个预训练模型 #timm中有多少个预训练模型 model_pretrain_list timm.list_models(pretrainedTrue) print(len(model_pretrain_list), model_pretrain_list[:3])3加载swin模型一般准会出错 model_ft timm.create_model(swin_base_pat…...
【java基础】java八大基本数据类型和运算符
文章目录说明八大基本数据类型整型浮点型字符型布尔类型类型转换java运算符基础运算符二元运算符自增自减运算符关系和boolean运算符三元运算符位运算符运算符优先级说明 这里介绍java的八大基本数据类型和运算符 八大基本数据类型 java中有八大数据类型,4个整型…...
Mybatis源码学习笔记(四)之Mybatis执行增删改查方法的流程解析
1 Mybatis流程解析概述 Mybatis框架在执行增伤改的流程基本相同, 很简单,这个大家只要自己写个测试demo跟一下源码,基本就能明白是怎么回事,查询操作略有不同, 这里主要通过查询操作来解析一下整个框架的流程设计实现。 2 Mybat…...
浅谈测试用例设计
前言 最近干的最多的事情就是设计测试用例、评审测试用例了,于是我不禁又想到了一个经典的问题:如何设计出优秀的测试用例? 可能有些童鞋看到这个问题会有些不以为然,这有什么好想的?干个测试谁还不会设计测试用例&a…...
python 利用装饰器实现类似于flask路由
例子1: def f1():print(1111)def f2():print(2222)if __name__ __main__:print(33)打印结果: 33 在例子1中,f1() 与f2() 都没有被调用,只执行了print(33) f1与f2,是没有被调用的,但是如果f1 和 f2 上面…...
git 拉取远程分支到本地
目录:***!本小作者,是将终端和Git的可视化插件结合使用,刚接触的可以自习看一下,内容简单,避免弯路!***一,简单了解远程分支1,连接远程:2,提交&am…...
Answering Multi-Dimensional Range Queries under Local Differential Privacy
文章目录AbstractIntroduction2 PRELIMINARIES2.12.2 Categorical Frequency Oracles4 GRID APPROACHES4.1概述Abstract 在本文中,我们解决了在局部差异隐私下回答多维范围查询的问题。有三个关键的技术挑战:捕捉属性之间的相关性,避免维度的…...
手把手搭建springboot项目05-springboot整合Redis及其业务场景
目录前言一、食用步骤1.1 安装步骤1.1.1 客户端安装1.2 添加依赖1.3 修改配置1.4 项目使用1.5 序列化二、应用场景2.1 缓存2.2.分布式锁2.2.1 redis实现2.2.2 使用Redisson 作为分布式锁2.3 全局ID、计数器、限流2.4 购物车2.5 消息队列 (List)2.6 点赞、签到、打卡 (Set)2.7 筛…...
Flutter基础语法(六)var、final、const、late
Flutter基础 第六章 Flutter关键字var、final、const、late的区别与使用 文章目录Flutter基础前言一、var1.var是什么?2.var如何使用3.var自动推断类型4.var可以再次赋值5.var指定类型二、final1.final是什么?2.final声明但不赋值3.final赋值多次4.final正常使用三、const1.…...
Linux之安装node
Linux之安装node步骤如下 1.去网站下载node 下载地址: https://npm.taobao.org/mirrors/ 2.上传到指定目录下 3.解压 tar -zxvf node-v17.3.0-linux-x644.配置node环境变量 //执行以下命令 vim /etc/profile //在path中加入以下内容 /usr/local/node-v15.14.0/b…...
二叉树、二叉搜索树、二叉树的最近祖先、二叉树的层序遍历【零神基础精讲】
来源0x3f:https://space.bilibili.com/206214 文章目录二叉树[104. 二叉树的最大深度](https://leetcode.cn/problems/maximum-depth-of-binary-tree/)[111. 二叉树的最小深度](https://leetcode.cn/problems/minimum-depth-of-binary-tree/)[129. 求根节点到叶节点…...
【算法】【数组与矩阵模块】求最长可整合子数组和子数组的长度
目录前言问题介绍解决方案代码编写java语言版本c语言版本c语言版本思考感悟写在最后前言 当前所有算法都使用测试用例运行过,但是不保证100%的测试用例,如果存在问题务必联系批评指正~ 在此感谢左大神让我对算法有了新的感悟认识! 问题介绍 …...
数据结构:循环队列的实现(leetcode622.设计循环队列)
目录 一.循环队列简单介绍 二.用静态数组实现循环队列 1.数组循环队列结构设计 2.数组循环队列的堆区内存申请接口 3.数据出队和入队的接口实现 4.其他操作接口 5.数组循环队列的实现代码总览 三.静态单向循环链表实现循环队列 1.链表循环队列的结构设计 2.创建静…...
[qiankun]实战问题汇总
[qiankun]实战问题汇总ERROR SyntaxError: Cannot use import statement outside a module问题分析解决方案子应用命名问题问题分析解决方案jsonpFunction详细错误信息问题分析解决方案微应用的注册问题Uncaught Error: application cli5-beta6-test-name died in status LOADI…...
Kafka(6):服务端常用参数配置
参数配置:config/server.properties # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership.…...
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
WEB3全栈开发——面试专业技能点P7前端与链上集成
一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...
对象回调初步研究
_OBJECT_TYPE结构分析 在介绍什么是对象回调前,首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例,用_OBJECT_TYPE这个结构来解析它,0x80处就是今天要介绍的回调链表,但是先不着急,先把目光…...
【PX4飞控】mavros gps相关话题分析,经纬度海拔获取方法,卫星数锁定状态获取方法
使用 ROS1-Noetic 和 mavros v1.20.1, 携带经纬度海拔的话题主要有三个: /mavros/global_position/raw/fix/mavros/gpsstatus/gps1/raw/mavros/global_position/global 查看 mavros 源码,来分析他们的发布过程。发现前两个话题都对应了同一…...
