JavaEE--Thread 类的基本用法(不看你会后悔的嘿嘿)
Thread类是JVM用来管理线程的一个类,换句话说,每个线程都唯一对应着一个Thread对象.
因此,认识和掌握Thread类弥足重要.
本文将从
- 线程创建
- 线程中断
- 线程等待
- 线程休眠
- 获取线程实例
等方面来进行具体说明.
1)线程创建
方法1:通过创建Thread类的子类并重写run () 方法
class MyThread extends Thread{@Overridepublic void run() {System.out.println("thread");}
}
public class Thread1 {public static void main(String[] args) {Thread thread = new MyThread();thread.start();System.out.println("main");}
}
方法2:通过创建Runnable接口的实现类并重写run ()方法,传实现类的对象作为构造器
class MyRunnable implements Runnable{@Overridepublic void run() {System.out.println("thread");}
}
public class Thread2 {public static void main(String[] args) {Thread thread = new Thread(new MyThread());thread.start();System.out.println("main");}
}
方法3:使用匿名类,new类,也就是创建该类的子类
public class Thread3 {public static void main(String[] args) {Thread thread = new Thread(){@Overridepublic void run() {System.out.println("thread");}};thread.start();System.out.println("main");}
}
方法4:使用匿名内部类,new接口,也就是创建该接口的实现类
public class Thread4 {public static void main(String[] args) {Thread thread = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("thread");}});thread.start();System.out.println("main");}
}
方法5:使用lambda表达式(日常开发中使用最多的形式)
public class Thread5 {public static void main(String[] args) {Thread thread = new Thread(()->{System.out.println("thread");});thread.start();System.out.println("main");}
}
2)线程中断
顾名思义,也就是让线程停止.
本质上而言,让线程停止,方法就一种 -->执行完线程入口方法(run ()方法).
只不过此处可能是正常执行结束,也可能是因为异常而导致结束.
目前常见的有以下两种方式:
1.使用自定义的变量来作为标志位
2.使用Thread提供的变量来作为标志位
下面来介绍:
方法1.使用自定义的变量来作为标志位
public class ThreadDemo9 {public static boolean isQuit = false;public static void main(String[] args) {// boolean isQuit = false;Thread t = new Thread(() -> {while (!isQuit) {System.out.println("hello t");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("t 线程终止");});t.start();// 在主线程中, 修改 isQuittry {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}isQuit = true;}
}
执行结果:

此处代码的逻辑大概就是,主线程sleep ()3秒后,t线程里的循环差不多执行3次(sleep()了3秒),此时isQUit被置为ture,t线程里循环结束.t线程继续向下执行逻辑,最终t线程正常结束.
假设:此处设置的isQuti不是类变量,而是局部变量,可行吗?
结果是显然不行的.那到底是什么原因呢?其实是因为-->lambda表达式存在变量捕获.
变量捕获,只能捕获到由1)final修饰2)实际上final的局部变量.
但是如果该局部变量的值被修改了,那么lamoda表达式就捕获不到该值了.
所以此处该如何做呢? --> 设置成类变量.也就是由static修饰的变量.
因为类变量不受变量捕获的限制.
方法2:使用Thread提供的变量来作为标志位
使用Thread.currentThreadOisInterrupted0 代替自定义标志位.
Thread 内部包含了一个 boolean 类型的变量作为线程是否被中断的标记.

public class ThreadDemo10 {public static void main(String[] args) {Thread t = new Thread(() -> {// currentThread 是获取到当前线程实例.// 此处 currentThread 得到的对象就是 t// isInterrupted 就是 t 对象里自带的一个标志位.while (!Thread.currentThread().isInterrupted()) {System.out.println("hello t");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}// 把 t 内部的标志位给设置成 truet.interrupt();}
}

原因如下:
首先需要明白interrupt 方法的作用:
1)设置标志位为 true
2)如果该线程正在阻塞中(比如在执行 sleep)此时就会把阻塞状态唤醒.通过抛出异常的方式让 sleep 立即结束.(线程在执行sleep(),join (),wait() 方法时,都会进入阻塞状态)
同时需要注意:
当 sleep 被唤醒的时候, sleep 会自动的把 Thread线程内置的标志位给清空(true -> false).这就导致下次循环,循环仍然可以继续执行了!!!
因此:如果需要结束循环,就得在 catch 中搞个 break.
此处再具体说明一下sleep() 的工作原理:(分3种情况)
1)如果 sleep 执行的时候看到这个标志位是 false --> sleep 正常进行休眠操作.
2)如果当前标志位为 true,sleep 无论是刚刚执行还是已经执行了一半,都会触发两件事 :1.立即抛异常2.清空标志位为 false.
3)如果设置 interrupt 的时候,恰好, sleep 刚醒~~ 这个时候赶巧了,执行到下一轮循环的条件,就直接结束了但是这种概率非常低,毕竟 sleep 的时间已经占据了整个循环体的 99.99999999% 的时间了.几乎可以视为不可能事件.
那可能就又会有人问了,为啥 sleep 要清空标志位呢???
目的就是为了让线程自身能够对于线程何时结束,有一个更明确的控制~
当前interrupt 方法,不是让线程立即结束,而是告诉他,你该结束了,至于他是否真的要结束,立即结束还是等会结束,都是代码来灵活控制的。
interrupt 只是通知,而不是"命令".
为什么这么说呢?原因就是,t线程是否结束,是取决于自身的,也就是说,根据catch里的逻辑实现,可以结束,也可以不结束.

那肯定又会有人问了:那为啥java 这里 不强制设定成命令结束"的操作? 只要调用 interrupt 就立即结束??
主要是设定成这种,非常不友好的~
线程 t 何时结束,一定是 t 自己最清楚~~ 交给 t 自身来决定比较好~~
映射到生活:如果正在跟领导打电话,你的女票让你去帮她拿东西.那此时,肯定是工作优先嘛!!些竟拿东西不是太重要的事,可以先搁置一会!!
3)线程等待
线程之间是并发执行的,操作系统对于线程的调度是无序的.无法判定两个线程谁先执行结束, 谁后执行结束!!!
在某些业务场景下,需要明确规定线程的结束顺序.可以使用线程等待来实现 -->join 方法

public class ThreadDemo {public static void main(String[] args) throws InterruptedException {Runnable target = () -> {for (int i = 0; i < 10; i++) {try {System.out.println(Thread.currentThread().getName() + ": 我还在工作!");Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName() + ": 我结束了!");};Thread thread1 = new Thread(target, "李四");Thread thread2 = new Thread(target, "王五");System.out.println("先让李四开始工作");thread1.start();thread1.join();System.out.println("李四工作结束了,让王五开始工作");thread2.start();thread2.join();System.out.println("王五工作结束了");}
}
输出结果:


当前是在main线程里执行的thread1.join()(也就是说是让main线程等待thread1线程).
那么在main线程里执行的thread1.join0 的时候,此时有两种情况:
1)如果 thread线程仍在继续运行,那么main线程就会暂时不参与程调度,等待thread1 线程结束main线程才继续执行代码逻辑.
2)如果thread1线程已经结束,那么main线程也就不用等待了,就直接继续执行自己的代码逻辑了.
但不管是哪种情况,都能保证thread1线程是先于main线程结束的.
4)线程休眠
方法:public static void sleep(long millis) throws InterruptedException
说明:
1)单位是ms
2)sleep是Thread类里的静态方法,通过类名可以直接调用.
3)作用是休眠当前进程.
4)需要用try-catch处理InterruptedException中断异常(意思就是 sleep 睡眠过程中,还没到点就提前唤醒了).
5)获取线程实例
方法:public static Thread currentThread()
说明:在哪个线程里调用,返回的就是哪个线程的对象引用.
public class ThreadDemo {public static void main(String[] args) {Thread thread = Thread.currentThread();System.out.println(thread.getName());}
}
输出结果:main
多提一句:多线程编程在Java中很常见,也很重要.务必掌握!!!
今天不想敲代码,所以才去敲.
uu们加油呀!!

相关文章:
JavaEE--Thread 类的基本用法(不看你会后悔的嘿嘿)
Thread类是JVM用来管理线程的一个类,换句话说,每个线程都唯一对应着一个Thread对象. 因此,认识和掌握Thread类弥足重要. 本文将从 线程创建线程中断线程等待线程休眠获取线程实例 等方面来进行具体说明. 1)线程创建 方法1:通过创建Thread类的子类并重写run () 方法 class M…...
MySQL数据库基本使用(二)-------数据库及表的增删改查及字符集修改
1.MySQL数据库的使用演示 1.1创建自己的数据库 命令格式如下(创建的数据库名称不能与已经存在的数据库重名): mysql> create database 数据库名;例如: mysql> create database atguigudb; #创建atguigudb数据库…...
互联网摸鱼日报(2023-03-17)
互联网摸鱼日报(2023-03-17) InfoQ 热门话题 开源新生代的成长之路:从校园到开源,需要迈过哪些挑战? 从 Clickhouse 到 Apache Doris,慧策电商 SaaS 高并发数据服务的改造实践 刚刚,百度文心…...
【前后端】低代码平台Jeecg-Boot 3.2宝塔云服务器部署流程
1 后端 部署流程 修改配置文件 更改数据库、redis的配置。 在system子模块中的target文件夹下生成 jar 包jeecg-boot-module-system-3.2.0.jar。 复制到云服务器 生成数据库 在这里插入图片描述 使用命令运行后端程序 java -jar ./jeecg-boot-module-system-3.2.0.jar宝…...
leetcode todolist
数组 数组的改变、移动 453. 最小移动次数使数组元素相等 665. 非递减数列 283. 移动零 数组的旋转 189. 旋转数组 396. 旋转函数 统计数组中的元素 645. 错误的集合 697. 数组的度 448. 找到所有数组中消失的数字 442. 数组中重复的数据 41. 缺失的第一个正数 数…...
改进YOLO系列 | CVPR2023最新 PConv | 提供 YOLOv5 / YOLOv7 / YOLOv7-tiny 模型 YAML 文件
DWConv是Conv的一种流行变体,已被广泛用作许多神经网络的关键构建块。对于输入 I ∈ R c h w I \in R^{c \times h \times w} I∈...
像ChatGPT玩转Excel数据
1.引言 最近ChatGPT的出现,把人工智能又带起了一波浪潮。机器人能否替代人类又成了最近热门的话题。 今天我们推荐的一个玩法和ChatGPT有点不一样。我们的课题是“让用户可以使用自然语言从Excel查询到自己想要的数据”。 要让自然语言可以从Excel中查数据&#…...
云原生之docker容器监控详解(cAdvisor、node exporter、prometheus)
docker容器监控一、前言二、cAdvisor2.1、安装cAdvisor2.2、使用Prometheus监控cAdvisor2.3、cAdvisor暴露的Prometheus指标三、Node Exporter3.1、安装Node Exporter3.2、指标四、Prometheus4.1、安装4.2、规则配置4.3、报警管理器五、grafana一、前言 cAdvisor源码 node exp…...
<Linux>进程概念
文章目录一、什么是进程1.进程概念2.进程描述 – PCB3.task_struct内容分类二、进程的基本操作1.查看进程2.结束进程3.通过系统调用获取进程标示符4.通过系统调用创建子进程(fork)三、进程状态1.普遍的操作系统状态2.Linux操作系统状态四、两种特殊的进程1.僵尸进程2.孤儿进程五…...
数据结构——顺序表
文章目录🐨0. 前言🎈1. 顺序表的概念及定义🪁2. 接口的声明🪄3. 接口的实现🍅3.1 为何使用断言?🍒3.2 初始化与销毁🍓3.3 尾插与尾删🍉3.4 头插与头删🍹3.5 指…...
闪存系统性能优化方向集锦?AC timing? Cache? 多路并发?
1. 从Flash系统的性能提升说起从消费级产品到数据中心企业级场景,NAND Flash凭借其高性能、大容量、低功耗以及低成本等特性大受欢迎,是目前应用最为广泛的半导体非易失存储介质。为了满足业务场景越来越严苛的性能要求,人们想了许多方法来提…...
【每日一题】——网购
🌏博客主页:PH_modest的博客主页 🚩当前专栏:每日一题 💌其他专栏: 🔴 每日反刍 🟢 读书笔记 🟡 C语言跬步积累 🌈座右铭:广积粮,缓称…...
百度终于要出手了?文心一言
文心一言 百度全新一代知识增强大语言模型,文心大模型家族的新成员,能够与人对话互动,回答问题,协助创作,高效便捷地帮助人们获取信息、知识和灵感。 前几天炒的风风火火的ChatGPT,虽然 ChatGPT 很强大&a…...
8年Java架构师面试官教你正确的面试姿势,10W字面试题带你成功上岸大厂
从最开始的面试者变成现在的面试官,工作多年以及在面试中,我经常能体会到,有些面试者确实是认真努力工作,但坦白说表现出的能力水平却不足以通过面试,通常是两方面原因: 1、“知其然不知其所以然”。做了多…...
Mybatis-Plus详解
简介MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。特性(官网提供)无侵入:只做增强…...
购物清单(蓝桥杯C/C++省赛)
目录 1 问题描述 2 文件的读取格式 3 代码实现 1 问题描述 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物。老板忙的时候经常让小明帮忙到商场代为购物。小明很厌烦,但又不好推辞。 这不,XX大促销又来了!老板…...
【蓝桥杯集训·每日一题】AcWing 4496. 吃水果
文章目录一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解三、知识风暴求组合数一、题目 1、原题链接 4496. 吃水果 2、题目描述 n 个小朋友站成一排,等着吃水果。 一共有 m 种水果,每种水果的数量都足够多。 现在&…...
selenium(6)-----unittest框架
unittest框架 1)测试固件 1)setUp()是用来初始化测试环境所做的工作 2)tearDown()是用来清理环境所做的工作 2)测试套件 把不同的测试脚本,不同类中的测试用例给组织起来放到一个测试套中执行 3)测试用例的要以test_开头 4)如何使用unittest框架 只需要在脚本中定义…...
统计软件与数据分析--Lesson3
dataframe数据常用python操作dataframe数据常用知识点1.创建dataframe1.1使用字典创建DataFrame:1.2使用列表创建DataFrame:1.3使用numpy数组创建DataFrame:1.4从TXT文件中创建DataFrame:1.5从CSV文件中创建DataFrame:…...
竞赛无人机搭积木式编程——以2022年TI电赛送货无人机一等奖复现为例学习(7月B题)
在学习本教程前,请确保已经学习了前4讲中无人机相关坐标系知识、基础飞行控制函数、激光雷达SLAM定位条件下的室内定点控制、自动飞行支持函数、导航控制函数等入门阶段的先导教程。 同时用户在做二次开发自定义的飞行任务时,可以参照第5讲中2021年国赛植…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
Pydantic + Function Calling的结合
1、Pydantic Pydantic 是一个 Python 库,用于数据验证和设置管理,通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发(如 FastAPI)、配置管理和数据解析,核心功能包括: 数据验证:通过…...
