多线程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.…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...
【堆垛策略】设计方法
堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下…...
五子棋测试用例
一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏,有着深厚的文化底蕴。通过将五子棋制作成网页游戏,可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家,都可以通过网页五子棋感受到东方棋类…...
Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...
