当前位置: 首页 > news >正文

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数据库,可以用作数据库、缓存、信息中间件(性能非常优秀,支持持久化到硬盘且高可用)。由于其自身特点,可以广泛应用在数据集群&#xff…...

跳槽,如果没有更好的选择,可以去美团试试···

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

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(下载需要点时间&#xf…...

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、当匿…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

django filter 统计数量 按属性去重

在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...

LLM基础1_语言模型如何处理文本

基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...

rknn toolkit2搭建和推理

安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 ,不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源(最常用) conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...

OCR MLLM Evaluation

为什么需要评测体系?——背景与矛盾 ​​ 能干的事:​​ 看清楚发票、身份证上的字(准确率>90%),速度飞快(眨眼间完成)。​​干不了的事:​​ 碰到复杂表格(合并单元…...

ThreadLocal 源码

ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物,因为每个访问一个线程局部变量的线程(通过其 get 或 set 方法)都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段,这些类希望将…...

HTTPS证书一年多少钱?

HTTPS证书作为保障网站数据传输安全的重要工具,成为众多网站运营者的必备选择。然而,面对市场上种类繁多的HTTPS证书,其一年费用究竟是多少,又受哪些因素影响呢? 首先,HTTPS证书通常在PinTrust这样的专业平…...