多线程的创建,复习匿名内部类,Thread的一些方法,以及lambda的变量捕捉,join用法
一、💛
Java的Thread类表示线程
1.创建类,继承Thread重写run方法
2.创建类,实现Runnable重写run方法
3.可以继承Thread重写run基于匿名内部类
4.实现Runnable重写run基于匿名内部类
5.lamdba表达式表示run方法的内容(推荐)
6。基于Callable(以后学)
7.基于线程池(以后学)
匿名内部类(不用看定义,看下面用法领悟):正常建类后面大括号,这一步相当于先创建一个子类,但是这个子类是没有名字(匿名),另一方面,这类的创建是在Demo这个类里面。
下面这个写法是3号💛💛
我们要记住一个是,最重要的是写run这个是赋予了线程需要做什么工作。
public class Demo {public static void main(String[] args) throws InterruptedException {Thread t=new Thread(){ //匿名内部类,看上面详细解答@Overridepublic void run() { //子类中重写了run方法,实现了线程要干的工作while(true){System.out.println("hello world");try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}}}};t.start(); //创建了该类的实例,并且是使用那个t这个引用指向。while (true) {System.out.println("love");Thread.sleep(1000);}}}
写法4😃😃
为什么括号不是封死的,因为小括号对应的是Thread构造方法的结束,new Runnable整个一段,都在构造出一个Thread的参数, 创建这个匿名内部类,通过构造方法传给Thread。
public class Demo {public static void main(String[] args) throws InterruptedException {Thread t=new Thread(new Runnable (){ //!!!括号不是封死的@Overridepublic void run() {while(true){System.out.println("hello world");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}} ) ; //!!!!!看这个小括号t.start();while (true) {System.out.println("love");Thread.sleep(1000);}}}
5.使用lambda(推荐的方法) 表示run方法的内容😗😗 (本质是匿名方法,这样的匿名函数,主要可以作为回调函数使用。——回调函数(合适的时候就干,不合适就选择不干。),不需要程序猿们主动去调动(需要知道函数名,才能被调动,常用场景 1.服务器开发 2.图形界面开发,用户的某个操作,触发回调),而是在合适的时机自动的被调动
Java本身不允许函数脱离类,但是lambda特例,起名叫“函数式接口”(😊必须只有一个方法😊)
类似于Lammbda这样的写法,本质上并没有新增新的语言特性,而是把以往实现的功能,换了一种更简单的方式编写。
public class Demo {public static void main(String[] args) throws InterruptedException {Thread t=new Thread(()->{ //也是没有右括号,在下面。while(true){System.out.println("hello world");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();while (true) {System.out.println("love");Thread.sleep(1000);}}}
二、 💚
Thread就是Java,线程的代言人,系统中一个线程,对应Java中一个Thread对象
public class Demo {public static void main(String[] args) throws InterruptedException {Thread t=new Thread(()->{while(true){System.out.println("hello world");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}},"myThread"); //给这个进程起名字t.start();while (true) {System.out.println("love");Thread.sleep(1000);}}}

Thread常见ID。线程的身份标识(JVM,给设定了一个标识)
一个线程可以存好几个身份标记:
1.JVM有一个身份标记
2.pthread库(系统给程序猿提供的操作线程的API,也有一个线程的身份标识)
3.内核里面,针对线程的PCB还有身份标识
Thread常见属性
id. getId()
name. getname()
状态。 getState() java中线程的状态和操作系统的有一定差异。
优先级 getPriority 设置获取优先级的作用不是很大,线程的调度,主要还是系统内核负责~系统的调度速度更快。
是否是后台进程 isDaemon()
后台进程/守护进程,后台进程不影响进程结束,(创建的线程默认是前端线程)前台进程会影响到进程结束,如果前台进程没执行完,进程是不会结束的。
一个进程的所有前台线程,都执行完退出了,那么即使存在后端线程没有执行完毕,也会随着进程一起退出
setDaemon(true) 把某一个进程,设置为后端进程,这样前端线程结束,后面的也结束了
public class Demo {public static void main(String[] args) throws InterruptedException {int n =0;Thread t=new Thread(()->{int m =0;while(m<9){System.out.println("hello world");m++;try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}},"myThread");t.setDaemon(true); //设置为后端线程t.start();while (n<3) { // 打印完事走完全部就结束了,所以一定会有这三个System.out.println("love"); n++;Thread.sleep(1000); }}}

是否存活 isAlive
Thread对象,对应的线程(在系统内核中)是否存活。
Thread对象,并不是和系统中的线程完全一样(同生共死)的。
一般的Thread对象,先创建好,~手动调用start ,内核才真正创造出线程
消亡的时候,
可能对象,先结束了生命周期(没有引用指向这个对象)
也有可能Thread对象还在,内核中的线程把run执行完成了,就结束了。
对象的整个生命周期大致可以分为7个阶段:
创建阶段、应用阶段、不可视阶段、不可到达阶段、可收集阶段、终结阶段、与释放阶段(了解就好)
重要方法start():真正创造出线程->调用系统API完成线程创建工作(本身是一瞬间完成的,相当于是传话的小弟,“你造个线程出来😈”,调用API之后代码立刻执行start之后的逻辑
操作系统=内核+配套的程序
一个系统最核心的功能:
1.对下管理好各种硬件设备
2.对上,给各种程序提供稳定的运行环境
操作系统的内核(应用程序):
创建线程,非常核心的功能,系统API,系统调用
一般情况应用,不可进入内核操作,不可进入内核的程序成为“用户态”
如果一些应用程序,能够进入后台,直接操作内核里面的一些数据结构,程序是出于“内核态”这样的程序还叫做驱动程序
三、💙
Thread的方法💙
(一个线程的run方法执行完毕,就算终止了。此时的终止此处线程,就是要想办法让run尽快执行完毕(正常不会出现run没执行完毕,突然就没了的情况)
(sleep相当于是停一会,不是说停止了)
1.程序猿们手动设置标志位,如
public static voolean isQuit=false;(写成成员变量,不会触发变量捕捉,而是内部类来访问成员变量, 看下面这个图,代码在后面,执行完isQuit=true; 线程就终止了,同时main也走完了。

public class Demo {public static boolean isQuit=false;public static void main(String[] args) throws InterruptedException {int n =0;Thread t=new Thread(()->{int m =0;while(!isQuit){System.out.println("hello world");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}},"myThread");t.start();while (n<3) {System.out.println("love");n++;Thread.sleep(1000);}isQuit=true; //手动终止}}
但是我们来看下面这个图,为什么我这样放进方法里面不可以呢?——这就源于我们lambda表达式的变量捕捉机制~
lambda可以捕获外界变量,这样lambda表达式执行的时机是更靠后的,这就导致,后续真正执行lambda时候,局部变量isQuit是否可能已经被销毁了呢?
这种情况是客观存在的,让lambda去访问一个已经被销毁的变量,很明显是不合适的,lambda引入了变量捕获这样的机制~,lambda去访问一个已经被销毁的变量,但明显是不合适的,lambda引入了变量捕获这样的机制~,lambda内部看起来是直接访问外部的变量,其实本质是把外部变量给复制了一份,到lambda里面(这样就可以解决刚才的生命周期问题了)(但是捕获变量有限制的,要求是be final(如同final,就是一个变量,我们后续没有修改他的操作) or effectively final(事实上的最终值 final修饰)

2.直接用Thread 类,给我们提供了现成标志位,不用手动, 🐶
while(!Thread.currentThread().isInterrupted())Thread.currentThread():的含义获取当前线程的对象Thread,提供静态方法,currentThread在哪个线程调动这个方法,就能够获取到哪个线程的引用(相当于就是t,但是不可以写t,写t是报错的)
isInterrupted()
对象内部,提供了一个标志位(boolean类型的)
true:结束
false:不结束

我们看上面的图能发现,为啥还会有异常呢?🐹,原因就是一个线程kennel正在运行,也可能处于sleep状态,如果线程sleep的过程中,是否应该把他唤醒你?
当然了,肯定要把他唤醒,但是sleep在唤醒的同时也会自动清除前面设置的标志位,给程序猿们留下操作空间,此时要是想让线程结束,则catch之后加一个break;
sleep唤醒之后,程序猿们一般有以下几种操作方式:
1.立即停下来,立即结束线程
2.忽略终止请求,继续循环(不写break)
3.继续做点别的事情,过一会再结束线程(catch之后执行别的逻辑,最后break;)
public class Demo {public static void main(String[] args) throws InterruptedException {int n =0;Thread t= new Thread(()->{int m =0;while(!Thread.currentThread().isInterrupted()){System.out.println("hello world");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();break;}}},"myThread");t.start();while (n<3) {System.out.println("love");n++;Thread.sleep(1000);}t.interrupt();}}
四、💗
等待线程——join
多个线程是并发执行的,具体的执行过程,都是由操作系统复制调度的!!!,操作系统的调度线程“随机的”(当然,是我们无法确定他的先后顺序)
等待线程就是一种规划线程结束顺序的手段~ A,B两个线程,希望B先结束,A后结束,此时就可以,让A线程调用B.join方法(去等待B)
此时B线程还没结束完,A线程就会进入阻塞状态,相当于给B留下了空间,B执行完毕之后,A再从阻塞状态中恢复回来,并且继续往后执行。,如果A执行到B.join的时候,B已经执行完,那么A就不用阻塞了,直接往下执行即可,如下图,他是等待,先把t这个线程走完了,再去走下面的main.
阻塞->该代码暂时不继续执行(该进程暂时不去cpu参与调度)sleep也能让该线程阻塞,但是是有时间限制的
join是死等,知道你完事,不然他不会开始(不推荐) 产生一个新的join(里面填写时间)最大等待时间。只要我时间到了,不管你来不来,我都走了(更推荐使用,这种时间版本,留有余地。)
可以被interrupt唤醒的等待操作:
1.join
2.sleep
3.wait

需要的自己拿着用呗
public class Demo {public static void main(String[] args) throws InterruptedException {int n =0;Thread t= new Thread(()->{int m =0;while(m<5){System.out.println("hello world");m++;try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}},"myThread");t.start();t.join(3000);while (n<3) {System.out.println("love");n++;Thread.sleep(1000);}}}
相关文章:
多线程的创建,复习匿名内部类,Thread的一些方法,以及lambda的变量捕捉,join用法
一、💛 Java的Thread类表示线程 1.创建类,继承Thread重写run方法 2.创建类,实现Runnable重写run方法 3.可以继承Thread重写run基于匿名内部类 4.实现Runnable重写run基于匿名内部类 5.lamdba表达式表示run方法的内容(推荐&#x…...
瑞吉外卖系统05
哈喽!大家好,我是旷世奇才李先生 文章持续更新,可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】更有我为大家准备的福利哟,回复【项目】获取我为大家准备的项目 最近打算把我手里之前做的项目分享给大家&#…...
D455+VINS-Fusion+surfelmapping 稠密建图(三)
继续,由surfelmapping建立的点云生成octomap八叉树栅格地图 一、安装OctomapServer 建图包 安装插件 sudo apt-get install ros-melodic-octomap-ros sudo apt-get install ros-melodic-octomap-msgs sudo apt-get install ros-melodic-octomap-server sudo apt-…...
rv1109/1126 rknn 模型部署过程
rv1109/1126是瑞芯微出的嵌入式AI芯片,带有npu, 可以用于嵌入式人工智能应用。算法工程师训练出的算法要部署到芯片上,需要经过模型转换和量化,下面记录一下整个过程。 量化环境 模型量化需要安装rk的工具包: rockchip-linux/rk…...
Android平台一对一音视频通话方案对比:WebRTC VS RTMP VS RTSP
一对一音视频通话使用场景 一对一音视频通话都需要稳定、清晰和流畅,以确保良好的用户体验,常用的使用场景如下: 社交应用:社交应用是一种常见的使用场景,用户可以通过音视频通话进行面对面的交流;在线教…...
--binlog-row-event-max-size
--binlog-row-event-max-size MySQL中用于控制rows格式的Binlog,binlog以chunk的方式存储,每个chunk的大小由binlog-row-event-max-size 进行控制; 如果event比较大的时候可以调大这个值;;改值必须是256的倍数&#…...
Jmeter命令行运行实例讲解
1. 简介 使用非 GUI 模式,即命令行模式运行 JMeter 测试脚本能够大大缩减所需要的系统资 本文介绍windows下以命令行模式运行的方法。 1.1. 命令介绍 jmeter -n -t <testplan filename> -l <listener filename> 示例: jmeter -n -t test…...
pl/sql函数如何返回多行数据?在线等......
编辑csm8109022010-01-27 09:59:18 这个问题我以前问过类似的,但一直没得到如意的答案!在oracle 里soctt的用户下的emp表,比如写一个函数,传入的参数为部门编号,然后返回所有该部门人员信息的函数。要用到游标&…...
Ubuntu Find命令详解
一、Find命令简介 Ubuntu的Find命令是一种常用的终端指令,用于在文件系统中查找符合条件的文件和目录。该命令的语法格式如下: find [PATH] [OPTION] [EXPRESSION]其中,PATH表示待查找的目录,OPTION为选项参数,EXPRES…...
ADS Momentum学习笔记
ADS Momentum的简介 ADS Layout界面仿真采用的方法主要是Momentum(矩量法)。 Momentum的特点 Momentum是高级设计系统(ADS)的重要组成部分,它提供了设计现代通信系统的电磁仿真。它可以用来计算一般平面电路的S参数…...
解决Vue3 使用Element-Plus导航刷新active高亮消失
解决Vue3 使用Element-Plus导航刷新后active高亮消失的问题 启用路由模式会在激活导航时以 index 作为 path 进行路由跳转 使用 default-active 来设置加载时的激活项。 接下来打印一下选中项index和index路径, 刷新也是没有任何问题的,active不会消失…...
K8S系列文章之 一键部署K8S环境
部署的原理是基于自动化部署工具 Ansible 实现的,需要提前安装Ansible 并配置下主机节点环境 1. 安装 Ansible 首先ansible基于python2.X 环境,默认centos都已经安装好了python2环境 // 最好更新下库 // yum update yum install -y epel-release yum i…...
Spring Boot、Spring Cloud、Spring Alibaba 版本对照关系及稳定兼容版本
Spring Boot、Spring Cloud、Spring Alibaba 版本对照关系及稳定兼容版本 引言 在 Java 生态系统中,Spring Boot、Spring Cloud 和 Spring Alibaba 是非常流行的框架,它们提供了丰富的功能和优雅的解决方案。然而,随着不断的发展和更新&…...
虫情监测仪介绍—技术原理、功能优势是什么?
KH-CQPest虫情监测仪是做好虫情监测的重要设备,利用虫情监测仪能够对农业大田、智慧温室、林业等场景的害虫分布情况及害虫种类进行监测,协助人们制定合理的防治措施。 1.技术原理: KH-CQPest虫情监测仪采用光学诱虫原理,配合传感…...
HTML5 Canvas和Svg:哪个简单且好用?
HTML5 Canvas 和 SVG 都是基于标准的 HTML5 技术,可用于创建令人惊叹的图形和视觉体验。 首先,让我们花几句话介绍HTML5 Canvas和SVG。 什么是Canvas? Canvas(通过 标签使用)是一个 HTML 元素,用于在用户计算机屏幕…...
ChatGPT在社交媒体聊天和评论分析中的应用如何?
ChatGPT在社交媒体聊天和评论分析中具有广泛的应用前景,可以帮助企业、个人和社会从多个角度更好地理解用户观点、趋势和情感。以下是详细的讨论: **1. 舆情分析与趋势预测:** ChatGPT可以用于分析社交媒体上的评论、帖子和消息,…...
DoIP学习笔记系列:(四)用CAPL脚本读取DID的关键点
文章目录 1. 如何在CAPL中读取DID?1.1 避坑如何新建CAPL工程,在此不再赘述,本章主要分享一下如何在CAPL中调用DoIP接口、diag接口进行DoIP和诊断的测试。 1. 如何在CAPL中读取DID? 通常在实际项目中,会有很多DID,各种版本号、各种观测量,如果手动点,显然很麻烦,如果要…...
chrome插件开发实例06-定制自己的Chrome DevTools调试工具
目录 Chrome DevTools 调试工具 演示 编辑 源码 devtools.html devtools.js panel.html panel.js...
安卓读取,添加,更新,删除联系人,读取短信
目录 读取联系人 添加联系人 更新联系人 删除联系人 读取短信 读取联系人 安卓可以通过contentResolver来读取联系人表,联系人表的Uri信息是:content://com.android.contacts/data/phones 从而输出联系人信息, 需要相关权限:…...
Practices6|69. x 的平方根、(哈希表)205. 同构字符串、(哈希表)1002. 查找共用字符
69. x 的平方根 1.题目: 给你一个非负整数 x ,计算并返回 x 的 算术平方根 。 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。 注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...
