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)则当前线程没有获得此对象的锁,自然不能此对象的锁,会报错;

海洋科学—物理海洋学 第五章 海洋环流 本章是基于《海洋科学导论》,但里面涉及到的重要的公式推导是专门拎出来推的,主要借鉴董昌明老师的《物理海洋学导论》,其中有一些多出来的推导,会在更新完整个物理海洋学之后重新拿出来一一讲解,最后开一个番外篇 阅读详情

相关推荐

CentOS 7环境下GLPI与OCS Inventory资产管理系统集成部署指南

本文详细介绍了在CentOS 7环境下,如何将GLPI与OCS Inventory两大开源工具进行集成部署,构建自动化资产管理系统。指南涵盖环境准备、核心服务安装、Web界面初始化、OCS插件配置及资产同步实战,帮助运维人员实现IT资产的自动发现、统一管理与可视化,大幅提升资产管理效率。

weixin_29274337的博客 326

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

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

梦否 1186

RK3588+TRL8367s 四网口千兆交换机配置与优化实战

本文详细介绍了基于RK3588高性能SoC与TRL8367s千兆交换芯片构建四网口交换机的完整实战流程。内容涵盖硬件连接、设备树配置、内核驱动加载、性能优化及常见问题排查,重点解析了RGMII时序调试、DSA架构配置等关键步骤,为嵌入式网络设备开发提供实用指南。

weixin_29266647的博客 672

wait、notify、sleep、interrupt对比分析

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

Littlemotor 1040

基于Android13的系统启动流程分析(三)之FirstStageMain阶段

init进程是Android系统中用户空间的第一个进程,作为第一个进程,它被赋予了很多极其重要的工作职责,比如创建zygote(孵化器)和属性服务等。init进程是由多个源文件共同组成的,这些文件位于源码目录system/core/init1. Bootloader 引导当按下设备电源键时,最先运行的就是 bootloader(固化在ROM的程序),bootloader 的主要作用就是硬件设备(如 CPU、flash、内存)的初始化并加载到RAM,通过建立内存空间映射,为装载 Linux 内核做好准备,。

q1210249579的博客 5496

WRF和WPS模型在Ubuntu系统上的安装与常见问题解决指南

本文详细介绍了在Ubuntu系统上安装WRF和WPS模型的完整教程,涵盖系统环境配置、依赖库安装、源代码编译以及常见问题的解决方案。重点解决了WPS编译中intmath.f文件的修改、环境变量设置和编译器兼容性等关键难点,帮助用户高效部署气象研究与预报模型。

weixin_29213525的博客 381

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

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

weixin_28901327的博客 462

YOLOv8的特征蒸馏代码应用讲解(CWD/MGD/mimic/在线蒸馏/逻辑蒸馏)

基于YOLOv8的逻辑蒸馏、特征蒸馏、在线蒸馏等方法代码介绍。

qq_41920323的博客 2582

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

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

m0_56825376的博客 1417

【保姆级教程】基于UNet++&MobileNetv2的语义分割模型从训练到RK3588部署:让边缘AI落地效率提升300%

通过SMP库一键构建encoder_name="mobilenet_v2", # 选择MobileNetv2作为骨干encoder_weights="imagenet", # 加载预训练权重加速收敛in_channels=3, # 输入图像通道数(RGB)classes=29, # Cityscapes数据集类别数activation=None # 输出无激活,便于后续损失计算本教程从“模型设计-训练-转换-边缘部署”全链路拆解了。

m0_71589036的博客 86

华为OD机试 - 商品推荐多属性排序 - 数组(Python/JS/C/C++ 双机位A卷 100分)

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。双十一来临,小王准备买某个购物平台买坚果。在输入坚果时,页面默认按照综合推荐列表。小王想知道这个综合排序时如何完成的,于是便开始思考算法题。经过一番操作后,完成它的多个关键词排序算法。希望你给小王提供一份正确的排序结果,验证其实现算法结果的准确性

学Java,找哪吒 622

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

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

TGO-Ming 1359

AUTOSAR进阶图解==>AUTOSAR_SWS_DefaultErrorTracer

AUTOSAR Default Error Tracer (DET)是AUTOSAR架构中的核心错误追踪模块,提供统一的错误报告机制。DET能够处理开发错误、运行时错误和瞬态故障三类问题,支持模块级和实例级的配置管理。模块架构上,DET通过Det_API接口与其他模块交互,可配置转发错误至诊断事件管理器(DEM)或调试日志追踪(DLT)。其配置结构包含全局参数和模块实例参数,允许灵活控制错误报告行为。DET在AUTOSAR 4.3.0版本中从DevelopmentErrorTracer扩展而来,增强了错误处

一名留德华的,康德的信徒的,专注于汽车电子领域的博客 909

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

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

ITSTAR 2669

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

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

怀旧版电脑GBC模拟器

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

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

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

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、付费专栏及课程。

余额充值