java中sleep、interrupt、wait、notify、join、yield用法

Java线程方法详解:sleep、yield、join、interrupt与线程状态流转 在多线程编程中,线程状态流转是理解并发控制的基石。Java线程从创建到终止会经历NEW、RUNNABLE、WAITING等状态,而Thread类中的sleep、yield、join、interrupt正是触发状态变化的核心工具。sleep让线程进入定时等待,且不会释放synchronized锁;join用于线程协作,底层通过wait实现等待与通知;interrupt则采用协作式中断机制,通过设置标志位唤醒阻塞线程。掌握这些方法的原理,能够帮助开发者设计高效的线程协作流程,如任务汇总、超时控制与优雅停机。在实 阅读详情

1) interrupt是Thread对象的方法,用于修改线程的打断状态为true(可以用isInterrupted()来获取),除此之外未做任何其他事,所以interrupt并不会去真正的打断某个线程的运行状态或杀死某个线程;

但是,当本线程在sleep阻塞或者wait阻塞或者join阻塞(本质还会wait阻塞)时,如果被interrupt,那么会在sleep或wait或join方法内抛出异常InterruptedException(可理解为本线程正在阻塞,没办法设置interrupt的状态,所以抛出异常),此时通过对异常InterruptedException的处理策略来决定本线程的后续工作:

a)自始至终不捕获异常,则会因异常而结束;

b)捕获后return,则结束本线程;

c)捕获后catch内的代码为空,则忽略此异常继续任务,此时interrupt起到一个打断阻塞的作用;

  所以interrupt只是去修改线程的打断状态,相当于是去提示线程,当线程未占用cpu时会抛出异常,其他的事情都有线程本身来决定,不会让调用interrupt的线程来决定,这是与notify有着本质不同的区别;

2) sleep是Thread的方法,让当前线程进入sleep阻塞(sleep block)一段时间(让出cpu)然后进入runable状态,如果当前线程此刻持有着同步锁,那么sleep阻塞的时候并不会释放同步锁;

注:sleep方法只可以在当前线程的内调用,是Thread类的静态方法,如主线程main与子线程t1,则在主线程内执行main.sleep(1000)是主线程暂停一秒,在子线程内调用t1.sleep(1000)是子线程暂停一秒,在主线程内调用t1.sleep(1000)还是主线程暂停一秒而不是子线程;

3) wait是Object对象的方法,

a) 是native方法,必须用在同步锁内的代码中,必须由持有当前同步锁的对象来调用wait方法,

b) 使当前线程(当前的同步锁代码)进入wait阻塞(wait block),wait阻塞会让出此对象持有的同步锁,

这是与sleep的重要区别;

wait(1000)会阻塞一秒后自动进入runnable状态,或者被interrupt或notify进入runnable状态;

wait( )无参方法或wait(0)会一直阻塞下去,除非被interrupt或notify;

但是当持锁对象是线程对象时(即Thread对象),此线程任务执行完毕后会调用notifyAll方法使所有此对象的wait阻塞被激活进入runnable状态,即使不被interrupt或notify也可以继续执行;

4) notify或notifyAll也是Object对象的方法,是与wait配合使用的,必须用在同步锁内的代码中,必须由持有当前同步锁的对象来调用,所以往往是在一个线程内调用a.wait(),然后在另一个先线程内调用a.notify()或a.notifyAll(),a为同一个对象;

先说两个概念:锁池和等待池
锁池:假设线程A已经拥有了某个对象(注意:不是类)的锁,而其它的线程想要调用这个对象的某个synchronized方法(或者synchronized块),由于这些线程在进入对象的synchronized方法之前必须先获得该对象的锁的拥有权,但是该对象的锁目前正被线程A拥有,所以这些线程就进入了该对象的锁池中。
等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁后,进入到了该对象的等待池中;
然后再来说notify和notifyAll的区别 如果线程调用了对象的wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去竞争该对象的锁。当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。也就是说,调用了notify后只要一个线程会由等待池进入锁池,而notifyAll会将该对象等待池内的所有线程移动到锁池中,等待锁竞争优先级高的线程竞争到对象锁的概率大,假若某线程没有竞争到该对象锁,它还会留在锁池中,唯有线程再次调用 wait()方法,它才会重新回到等待池中。而竞争到对象锁的线程则继续往下执行,直到执行完了 synchronized 代码块,它会释放掉该对象锁,这时锁池中的线程会继续竞争该对象锁。
综上,所谓唤醒线程,另一种解释可以说是将线程由等待池移动到锁池,notifyAll调用后,会将全部线程由等待池移到锁池,然后参与锁的竞争,竞争成功则继续执行,如果不成功则留在锁池等待锁被释放后再次参与竞争。而notify只会唤醒一个线程。

wait应该永远在被synchronized的背景下和那个被多线程共享的对象上调用,下一个一定要记住的问题就是,你应该永远在while循环,而不是if语句中调用wait。因为线程是在某些条件下等待的——在我们的例子里,即“如果缓冲区队列是满的话,那么生产者线程应该等待”,你可能直觉就会写一个if语句。但if语句存在一些微妙的小问题,导致即使条件没被满足,你的线程你也有可能被错误地唤醒。

Java 中可以用 wait、notify 和 notifyAll 来实现线程间的通信

5) join( )  join( 1000)方法的作用是让出当前线程的执行权给另外一个线程(一定时间),可以控制线程执行顺序,如在main线程中执行

System.out.println("1");

t1.join();

System.out.println("2");

t2.join(1000);

System.out.println("3");

则main线程在输出1之后等待,让线程t1来执行,t1指向完毕后输出2,然后再次等待,等待t2执行完毕后或等待一秒后继续运行,输出3;

从join()的源码看,如果线程被生成了,但还未被起动,调用它的 join() 方法是没有作用的,将直接继续向下执行;

join( 0)与join( )一样,是一直等待下去,直至线程执行完毕;

join是一个有synchronized修饰的方法,其内部还是调用了wait方法(小提示:Object 提供的方法), 其实join方法本质就是利用线程实例作为对象锁的原理,在join方法内调用“线程实例.wait()”(是会判断线程示例是否在运行中isAlive),保持在wait阻塞状态,当线程终止时,会调用线程自身的notifyAll()方法,通知所有等待在该线程对象上的线程的特征,这样外面的线程就可继续执行了。

当main线程调用t.join时候,main线程会获得线程对象t的锁(wait 意味着拿到该对象的锁),调用该对象的wait(等待时间),直到该对象唤醒main线程 ,比如退出后。这就意味着main 线程调用t.join时,必须能够拿到线程t对象的锁(所以t不一定是在调用join后立即执行,如果锁不空闲则需要等待锁)。

6) yield Thread的静态方法,是native方法,该方法用于使当前线程主动让出档次cpu时间片,回到runnable状态,的等待下次分配时间片;因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。
结论:yield()从未导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。

7) 

Object.wait(),Object.notify(),Object.notifyAll()都是Object的方法,换句话说,就是每个类里面都有这些方法。

Object.wait():释放当前对象锁,并进入阻塞队列
Object.notify():唤醒当前对象阻塞队列里的任一线程(并不保证唤醒哪一个)
Object.notifyAll():唤醒当前对象阻塞队列里的所有线程
为什么这三个方法要与synchronized一起使用呢?解释这个问题之前,我们先要了解几个知识点
每一个对象都有一个与之对应的监视器
每一个监视器里面都有一个该对象的锁以及一个等待队列(等待池)和一个同步队列(锁池)

wait()方法的语义有两个,一是释放当前对象锁,另一个是进入等待队列,
如果不在synchronized中(或非所对应的对象来wait)则当前线程没有获得此对象的锁,自然不能释放此对象的锁,会报错;
notify()方法也是一样的,用来唤醒一个线程,你要去唤醒,
如果不在synchronized中(或非所对应的对象来notify)则当前线程没有获得此对象的锁,自然不能此对象的锁,会报错;

S32K3基于EB配置GPT触发WDG的实战解析 本文详细解析了S32K3 MCU基于EB tresos工具配置GPT定时器触发看门狗(WDG)的实战方法。通过分析协同工作机制、MCAL配置步骤及代码实现,帮助开发者构建可靠的硬件监控系统,提升汽车电子系统的安全性与实时性。 阅读详情

相关推荐

一文告诉你:如何在trae中编译运行STM32程序,并让AI帮你修改代码

本文详细介绍了如何将STM32程序从Keil迁移到国产免费工具Trae,并利用AI进行代码修改的全过程。

水滴爬呀爬 4881

wait()、join()、sleep()、yield() 和 interrupt()方法

Object的wait方法:wait指线程处于进入阻塞状态,不占用任何资源,不增加时间限制。 Thread的sleep方法: sleep指线程被调用时,占着CPU不工作,其他线程无法进入,会增加时间限制。 Thread的yield方法:yield()的作用是让步。它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权;但是,并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权;也有可能是当前线程又进入到“运行状态”继续运行!..

梦否 1186

STM32单片机远程升级

stm32远程升级

fang_yang_wa的博客 1万+

wait、notify、sleep、interrupt对比分析

方法简述 Thread类 sleep:暂停当前正在执行的线程;(类方法) yield:放弃当前CPU资源,让其他任务去占用CPU执行时间,放弃的时间不确定,有可能刚刚放弃,马上又获得CPU时间片。(类方法) join:等待该线程终止; interrupt:仅仅是在当前线程上做一个停止的标记,并不会真正的停止线程,与interrupted()静态方法或isInterrupted()实例方法配合使用,达到中断线程的目的。当线程调用wait(),sleep(),join()或I/O操作时,将收到Inte

Littlemotor 1040

香橙派5Max + Realsense D435i + Fast-Drone-250:手把手教你搭建一个完整的无人机视觉开发环境

本文详细介绍了如何利用香橙派5Max、Realsense D435i深度相机和Fast-Drone-250项目搭建完整的无人机视觉开发环境。从硬件连接到ROS配置,再到项目部署与性能优化,提供全栈式实战指南,助力开发者快速实现SLAM算法验证和自主导航功能开发。

weixin_30879169的博客 460

【机器学习】一文搞懂算法模型之:Transformer

必会算法模型之:Transformer

商务合作 | 面试培训 | 职场规划 ==>主页扫码 5608

java线程状态wait()_Java线程状态及 wait、sleep、join、interrupt、yield等的区别

wait:Object类的实例方法,释放CPU执行权,进入等待状态,直到 被中断、被拥有该对象锁的线程唤醒(notify或notifyAll)、wait时间到了自己唤醒 三者之一发生。会释放所持有的对象锁。(关于 wait、notiy、notifyAll的配合原理见后面)示例:wait()和notify()因为会对对象的“锁标志”进行操作,所以它们必须在获得对象锁后执行即在 synchroniz...

weixin_28901327的博客 462

西门子G120变频器在立体仓库堆垛机应用参数设置

本文详细介绍了G120 CU240E及CU250S变频器的参数设置流程。主要内容包括:1)快速调试步骤,从新建项目、扫描节点到设置电机类型、负载类型等参数;2)抱闸参数设置方法;3)参数下载异常时的处理方案。重点说明了通过STARTER软件进行向导式调试的完整过程,包括电机铭牌参数输入、识别方式选择等关键环节,并提示了通讯连接注意事项。当下载失败时,提供了通过导入导出项目文件解决问题的具体方法。

xdpcxq的专栏 863

关于interrupt方法打断wait和sleep的感悟

关于interrupt方法打断wait和sleep的感悟,以及一些常见的问题

m0_56825376的博客 1417

【Spring Cloud Alibaba】Linux安装RocketMQ以及RocketMQ Dashboard可视化工具

在当今分布式架构的开发中,消息队列成为了一种常见的解决方案。RocketMQ是阿里巴巴开源的分布式消息中间件,具有高吞吐量、高可用性和强大的扩展性,因此在构建大规模、高可靠性的应用系统时备受推崇。而在使用RocketMQ时,为了更好地了解消息的流动和监控,RocketMQ Dashboard成为了一个不可或缺的可视化工具。本篇博客将带大家一步步在Linux系统中安装RocketMQ,并介绍如何配置和使用RocketMQ Dashboard。

编码人生 3382

【一看就会】Autoware.universe中静态绕障路线的生成逻辑

在路径行为规划中,前期根据地图和起点终点,生成了一组连续可行的路径段序列(lanelets),然后后续路径行为规划,又会进行起始点,终止点,避障绕障路径的路径规划,并且会调用route_handler中的函数,进行中心线生成,最后生成路径,后续再给速度行为规划进行速度规划。在autoware.universe的规划中,是基于规则的规划,而其中的规则又是为了解决不同场景的。而这些场景,大部分是为了解决路上障碍物(静态、动态、行人、车辆等等)。

weixin_48386130的博客 321

Java 多线程的wait,notify,notifyAll,sleep,interrupt方法

wait()、notify()和notifyAll()这三个方法都依赖于Java对象的监视器锁(也称为内置锁或互斥锁)。调用这些方法时,当前线程必须持有该对象的监视器锁,所以通常它们三都与synchronized 关键字一起使用,否则将抛出IllegalMonitorStateException异常(也就是没有获取对象的监视器锁和调用了这些方法)。

TGO-Ming 1359

Unity小游戏接入抖音敏感词检测

摘要: 本文介绍了Unity小游戏接入抖音敏感词检测的方法。抖音官方提供了两种API:SensitiveWordCheck用于检测敏感词,ReplaceSensitiveWords用于替换敏感词。此外,若使用键盘输入事件,可通过tt.onKeyboardComplete监听回调,平台会自动屏蔽敏感词(替换为*)。接入官方字库可有效避免审核驳回,适用于小游戏中的用户输入功能(如起名系统)。附官方文档链接及参数说明。

类人_猿的博客 4593

Java线程中sleep()、wait()和notify()和notifyAll()、suspend和resume()、yield()、join()、interrupt()的用法和区别

从操作系统的角度讲,os会维护一个ready queue(就绪的线程队列)。并且在某一时刻cpu只为ready queue中位于队列头部的线程服务。 但是当前正在被服务的线程可能觉得cpu的服务质量不够好,于是提前退出,这就是yield。 或者当前正在被服务的线程需要睡一会,醒来后继续被服务,这就是sleep。 sleep方法不推荐使用,可用wait。 线程退出最好自己实现,在运行状态中一

ITSTAR 2669

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Java-线程中sleep()、wait()和notify()和notifyAll()、suspend和resume()、yield()、join()、interrupt()的用法和区别

Java线程中sleep()、wait()和notify()和notifyAll()、suspend和resume()、yield()、join()、interrupt()的用法和区别 从操作系统的角度讲,os会维护一个ready queue(就绪的线程队列)。并且在某一时刻cpu只为ready queue中位于队列头部的线程服务。 但是当前正在被服务的线程可能觉得cpu的服务质量不够好,于是...

脑壳疼 200

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

wait,notify,sleep,yield,join,interrupt,isInterrupted 方法总结

java 多线程相关方法总结(wait,notify,sleep,yield,join,interrupt,isInterrupted ,synchronized 代码块和方法)java 中 object 对象的隐藏属性——monitor 和 wait set.java中 任何一个对象 都有以上两个涉及到 多线程并发 方面的隐藏属性。监视器 和 等待队列。  有些方法执行时,需要拥有对象的锁。...

iteye_4926的博客 186

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

wait、notify、join、yield、sleep、interrupt的介绍

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34249678的博客 140

Java线程中sleep()、wait()和notify()和notifyAll()、yield()、join()等方法的用法和区别

Java线程中sleep()、wait()和notify()和notifyAll()、suspend和resume()、yield()、join()、interrupt()的用法和区别从操作系统的角度讲,os会维护一个ready queue(就绪的线程队列)。并且在某一时刻cpu只为ready queue中位于队列头部的线程服务。但是当前正在被服务的线程可能觉得cpu的服务质量不够好...

weixin_30347009的博客 67

JAVA线程相关常见方法

简述 本文主要介绍wait()、notify()、notifyAll()、join()、sleep()、yield()的含义与用法。 wait() 当线程调用一个共享变量(对象锁)的wait方法时,该线程会被阻塞挂起,直到发送以下事件: 其他线程调用该共享变量(对象锁)notify()、notifyAll()方法 其他线程调用该线程的interrupt方法。 注: 如果调用 wait()方法...

solo_jm的博客 166

线程生命周期及五种状态

其他阻塞:通过调用sleep方法或者join方法或者发出I/O请求时,线程会进入阻塞状态,当sleep()状态超时,或者join()等待线程终止或者超时,或者I/O处理完毕,线程重新转入就绪状态;当前线程调用join(),则线程转为阻塞状态,eg:A线程中插入了B.join(),则B先执行,执行完,A线程继续执行;调用该方法,线程进入waiting状态,只有等待另外的线程通知或被中断才会返回,调用wait()后,会释放对象锁,因为wait方法一般用在同步方法或者同步代码块中。

一个喜欢诗和远方的程序媛 2768

java线程中的常用方法_多线程中的常用方法

一、wait()、notify()、nofityAll()方法在Object.java中,定义了wait(), notify()和notifyAll()等方法。wait()的作用是让当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的锁。而 notify()和notifyAll()的作用,则是唤醒当前对象上的等待线程;notify()是唤醒单个线程,而notifyAll()是唤醒所...

weixin_39709979的博客 103

创建线程的三种方式

Thread:继承Thread类,重写 run() 方法,实例化后调用 start() 方法 Runnable:实现Runnable接口,重写 run() 方法,传入Thread类的构造函数中,然后调用Thread类的 start() 方法 Callable:实现 Callable 接口,重写 call() 方法,传入FutureTask类的构造函数中,然后将FutureTask的实例传入Thread类的构造函数中,然后调用Thread类的 start() 方法 public class M..

imonkeyi的博客 388
上一篇: 浅谈java中继承Thread与实现Runable的区别
下一篇: Java锁Synchronized不同用法的区别
ArtisticProgramming
博客等级 码龄8年 1粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值