JavaEE(系列3) -- 多线程(线程的中断与线程等待)
新内容开始之前,我们总结一个知识点.
Thread类中的start方法和run方法的区别?
start():
用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行, 然后通过此Thread类调用方法run()来完成其运行操作的, 这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调度其它线程。 一旦得到cpu时间片,就开始执行run()方法,这里方法 run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止.
run():
run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。
总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。这两个方法应该都比较熟悉,把需要并行处理的代码放在run()方法中,start()方法启动线程将自动调用 run()方法,这是由jvm的内存机制规定的。并且run()方法必须是public访问权限,返回值类型为void。
目录
1. Thread 类的方法
2. 线程中断
2.1 设置一个结束标志位
2.2 interrupt() (Thread 中自带的标志位)
2.3 为什sleep要清空标志位?
3.线程等待
1. Thread 类的方法
2. 线程中断
线程的中断,就是将一个线程停下来.
线程的终止:本质上只有一种,就是让该线程的入口方法执行完毕.
2.1 设置一个结束标志位
/*** Created with IntelliJ IDEA.* Description:线程中断1-自己创建变量,控制循环* User: YAO* Date: 2023-05-08* Time: 16:28*/
public class ThreadDemo7 {public static boolean isQuit = false;public static void main(String[] args) {Thread thread = new Thread(()->{while (!isQuit){System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("新线程结束");});thread.start();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}isQuit = true;}
}
通过主线程进行修改标志位,使得新线程中的代码停止了循环.
思考:此时如果将isQuit,不写成成员变量,写在Main方法之中,还会达到想要的效果吗?
答案:不可以 虽然lambda表达式能够访问局部变量,但是lambda表达式有变量捕获,捕获的变量必须是没有进行修改过的变量,main方法中后面对isQuit做了修改,所以不可以写在main方法中.这个变量要么是被final修饰,如果不是被final修饰的 你要保证在使用之前,没有修改.
2.2 interrupt() (Thread 中自带的标志位)
public class ThreadDemo8 {public static void main(String[] args) {Thread thread = new Thread(()->{//currentThread() 获取当前线程的实例while (!Thread.currentThread().isInterrupted()){System.out.println("hello t");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();//打印当前异常位置的调用栈}}});thread.start();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}//将标志位设置为truethread.interrupt();}
}
简要介绍一下上面的代码.
首先认识两个方法:
1. Thread.currrentThread() :是获取当前线程的实例.
2. Thread.currrentThread() .isInterrupted() --->默认是false
interrupt方法的作用: * 1.设置标志位为true * 2.如果该线程处于堵塞的状态(比如正在执行sleep),此时就会把阻塞状态给唤醒.通过抛出异常的方式让sleep立即结束.
当我们运行上述代码的时候,我们会看见下述问题
出现的原因:
主线程中通过设置标志位interrupt,就立刻将sleep给唤醒,当sleep被唤醒的时候,sleep会自动的把isInterrupted标志位给清空 (true->flase),这样新线程的循环就被打通了,继续的执行sleep下一次遇见的时候就标志位就是false,那么就执行sleep本身,也不抛出异常,循环一直走下去,如果想要该循环截止,就在抛出异常的时候加一个break.
多线程的代码执行顺序不是“从上到下”,而是每个线程独立执行的。
2.3 为什sleep要清空标志位?
清空标志位的目的是让线程本身能够对于线程何时结束,有一个更明确的控制.
当前的interrupt方法效果,并不是让线程立即结束,而是告诉他,你该结束了,至于他是否真的要结束,立即结束还是等会结束,都是代码来灵活控制的。
interrupt只是建议,不是命令。为什么java不强制设定为“命令结束”的操作呢?只要调用interru就立即结束呢?因为设定成这种,非常不友好。线程t何时结束,一定是t自己最清楚。交给t自己决定,就比较好。
3.线程等待
使用thread.join()
线程之间是并发执行的。操作系统对于线程的调度是无序的,无法判定两个线程谁先执行结束,谁后执行结束。
package threading;public class ThreadDemo8 {public static void main(String[] args) {Thread t=new Thread(()->{System.out.println("hello t");});t.start();System.out.println("hello main");}
}
上述代码中,先输出hello main 还是先输出hello t是无法确定的,大概率先输出hello main.必定创建线程是需要开销的,但是我们海狮无法确定优先顺序,这就引出一个问题,当我们需要一个场景就是,必须等待线程2执行完了再执行线程1,这时候我们怎么办呢?
使用关键字 join
public class ThreadDemo9 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(()->{System.out.println("hello t");});thread.start();System.out.println("hello main1");//在main线程中调用thread.join,main线程等待Thread线程,等Thread执行完了之后,在继续执行main线程.thread.join();System.out.println("hello main2");}
}
上述代码的意思是,在主线程中加了一个t.join,就是等待t线程结束之后,再执行t.join之后的main线程中的代码.也就是在t线程结束之前,main线程处于一个堵塞的状态,暂时不参加CPU的调度执行.运行结果如下:
补充:
join还有一个版本,可以填写一个参数,作为“超时时间”,等待的最大时间。
join的无参数版本,效果就是“死等”,不见不散。
join的有参数版本,则是执行最大超时时间,如果等待的时间到了上限,还没有等到,咱就不等了。
那么此时就会联想到一个问题,会不会出现两个线程互相等待的情况.
答案:是会出现的 那种情况称为死锁,是bug。 比如家钥匙锁车里了,车钥匙锁家里了。
相关文章:

JavaEE(系列3) -- 多线程(线程的中断与线程等待)
新内容开始之前,我们总结一个知识点. Thread类中的start方法和run方法的区别? start(): 用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程&#…...
想装一台自己的电脑,可以先了解下这些问题
时间:2023年5月11日19:09:56 ✨✨✨问题清单: ↪️计算机中CPU和内存是什么?分别有什么作用? ↪️为什么计算机中要有内存?CPU访问内存中的数据和访问硬盘中的数据有什么差别? ↪️CPU的基准速度表示什…...

Redis未授权漏洞复现
Redis简介 Redis是C语言开发的一个开源高性能(key-value)键值对类型的内存NoSQL数据库,可以用作数据库、缓存、信息中间件(性能非常优秀,支持持久化到硬盘且高可用)。由于其自身特点,可以广泛应用在数据集群ÿ…...

跳槽,如果没有更好的选择,可以去美团试试···
在美团干了半年,说一下自己的感受,美团是一家福利中等,工资待遇中上,高层管理团队强大,加班强度一般,技术不错,办公环境一般,工作氛围中上,部门差距之间工作体验差距巨大…...

Java10
Java10 (一)、配置文件(二)、多线程2.1 并发和并行2.2 多线程的实现方式2.3 常见成员方法2.3.1 线程的优先级2.3.2 守护线程(备胎线程)2.3.3 礼让线程和插入线程 2.4 线程生命周期2.5 线程安全问题2.6 锁2.…...
IMS call通话类型对比差异
IMS call呼入/呼出流程对比 呼出MO call大致流程 1)UE发送INVITE消息发起IMS call 2)UE接收网络返回的100 Trying 3)UE接收183 Session Progress 4)UE发送PRACK确认收到183 5)UE接收200 OK(PRACK) 6)UE发送UPDATE进行precondition流程 7)UE接收200 OK(UPDATE) 8…...

5.2 中心极限定理
学习目标: 要学习中心极限定理,我会采取以下几个步骤: 学习基本概念:了解什么是随机变量、样本、总体、概率密度函数等基本概念,为学习中心极限定理打下基础;学习正态分布:中心极限定理的核心…...
JVM 内存分哪几个区,如和判断一个对象是否存活
JVM 内存分哪几个区,每个区的作用是什么? java 虚拟机主要分为以下一个区:方法区: 1. 有时候也成为永久代,在该区内很少发生垃圾回收,但是并不代表不发生 GC,在这里进行的 GC 主要是对方法区里的常量池和对类型…...
在Spring Boot微服务使用Jedis操作Redis List列表
记录:408 场景:在Spring Boot微服务使用Jedis操作Redis List列表。 版本:JDK 1.8,Spring Boot 2.6.3,redis-6.2.5,jedis-3.7.1。 1.微服务中配置Redis信息 1.1在application.yml中Jedis配置信息 hub:example:redis:jedis:host: 192.168.…...

springboot + vue 部署 阿里云云服务器 ECS
安装所需文件 安装mysql5.7 下载MySQL的yum源配置 wget http://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm安装MySQL的yum源 yum -y install mysql57-community-release-el7-11.noarch.rpm使用yum方式安装MySQL5.7(下载需要点时间…...
mysql 日期 计算 时间差 天数差
mysql计算两个日期的时间差 第一种:TIMESTAMPDIFF函数 三个参数。第一个参数是比较的类型:FRAC_SECOND、SECOND、 MINUTE、 HOUR、 DAY、 WEEK、 MONTH、 QUARTER、YEAR几种类型。第二、三参数是时间,后减前: SELECT TIMESTAMPDIFF(DAY,20…...

不用网闸、FTP的话 如何实现内外网数据交换?
网络隔离已然成为很多企业首选的数据保护方式,即使是内部人员之间,也是不能随意的发送敏感文件的。但是,文件的流转交互,又是不可避免的,网络隔离保障了企业网络安全,但在具体实践中仍需解决各隔离网间的数…...
探寻Spring MVC的奥秘:内部组件与工作流程详解
Spring MVC是一个基于MVC架构模式的Web框架,是Spring框架的一个组件。它提供了一套Web应用程序开发的全面解决方案,包括从请求到响应的处理流程、处理请求的控制器、视图解析器、国际化和验证器等。 在这篇文章中,我们将介绍Spring MVC框架的…...
eclipse svn ClassNotFoundException: javassist.ClassPool
eclipse 五月 10, 2023 9:26:49 上午 org.apache.catalina.core.StandardContext filterStart 严重: Exception starting filter struts2 java.lang.reflect.InvocationTargetException - Class: com.opensymphony.xwork2.inject.ContainerImpl M e t h o d I n j e c t o r F…...
广度优先遍历搜索迷宫最短路径
思路分析 由于广度是扩散逐层的方式遍历,相当于是多条路同时跑,最后先到终点就是最短路径了。 广度优先搜索主要使用队列来进行处理 路径用一个单独的vector存储,每一个点的坐标由二维转为一维,如(2, 3)存储在vector中下标为2*…...
分布式计算基础知识
分布式系统的概念 分布式系统是由多个独立计算机组成的系统,这些计算机通过网络进行通信和协作,共同完成一个任务。分布式系统的特点是具有高可用性、可扩展性和容错性。 在分布式系统中,每个计算机节点都可以独立地执行任务,同…...

Mybatis方式完成CRUD操作
Mybatis方式完成CRUD操作 文章目录 Mybatis方式完成CRUD操作1、java以Mybatis方式操作DB1.1、配置数据源-创建 resources/mybatis-config.xml1.2、创建java bean-Monster1.3、配置Mapper接口声明方法1.4、配置xxMapper,完成SQL配置,实现CRUD操作1.5、Test测试 2、需…...
css背景 background的属性作用和值
当我们在 HTML 中设置背景时,可以使用 background 属性。这个属性有多个值,可以使用不同的值来设置背景图片、背景颜色、背景位置、背景重复等等。以下是用表格列出的常见的 background 属性的值及其作用: 属性值描述background-color设置背…...
六大行文化特色知识(上)
中国六大银行都是综合性大型商业银行,业务涵盖面广泛且多元,代表着中国金融界最雄厚的资本和实力,这也是为什么很多毕业生想进国有行的原因,今天小编就带大家来了解一下关于六大行的特色知识,从如信银行考试中心平台了…...

匿名对象的特性和使用场景你知道吗?
目录 一、匿名对象的概念 二、单参数和多参数构造场景的匿名对象 ①只有一个参数的构造函数 ②多个参数的构造函数 三、使用匿名对象作为函数的参数的缺省值 四、只为调用类中的一个函数时 五、匿名对象的特性 1、匿名对象的生命周期只有一行 2、匿名对象具有常性 3、当匿…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...