首页 > 编程语言 >Java线程的sleep和wait的区别

Java线程的sleep和wait的区别

时间:2024-11-14 15:19:52浏览次数:3  
标签:Java Thread Object InterruptedException 线程 sleep wait

       在Java中,Thread.sleep()Object.wait() 都可以让线程暂停执行,但是它们的作用机制和使用场景是不同的。下面是这两个方法的主要区别:

Thread.sleep(long millis, int nanos)

  • 参数millis 是毫秒数,nanos 是额外的纳秒数(0到999,999之间)。
  • 行为:当前线程将暂停执行至少指定的毫秒数加上纳秒数。实际暂停时间可能会更长,因为系统调度或其他因素可能会导致额外的延迟。
  • 锁的影响Thread.sleep() 不会影响线程所持有的锁。如果线程在调用 Thread.sleep() 之前持有了某个对象的锁,那么即使在线程暂停期间,这个锁也不会被释放。
  • 异常处理:如果另一个线程中断了正在睡眠的线程,那么会抛出 InterruptedException,并且清除中断状态。因此,在调用 Thread.sleep() 后应该总是捕获 InterruptedException 并进行适当的处理。
  • 应用场景:适用于简单的定时任务,比如每隔一段时间执行一次某些操作。
  • 用法

              基本用法:使用 Thread.sleep(millis) 或 Thread.sleep(millis, nanos) 让线程暂停指定的时间。 

               异常处理:必须捕获 InterruptedException,因为如果在 sleep 期间线程被中断,就会抛出这个异常。处理中断异常的一种常见做法是重新设置中断标志,然后退出当前操作。

示例
try {
    Thread.sleep(1000); // 使当前线程暂停1秒钟
} catch (InterruptedException e) {
    // 重设中断状态
    Thread.currentThread().interrupt();
    System.out.println("Thread was interrupted during sleep.");
}

Object.wait()

  • 参数wait() 可以接受三个不同的签名:
    • void wait(): 无限期等待,直到被其他线程唤醒。
    • void wait(long timeout): 等待指定毫秒数后自动醒来。
    • void wait(long timeout, int nanos): 等待指定的毫秒数加纳秒数后自动醒来。
  • 行为:当前线程必须首先获取调用 wait() 方法的对象的锁。调用 wait() 后,线程会释放该对象的锁,并进入等待队列。直到其他线程调用了同一个对象的 notify() 或 notifyAll() 方法,或者指定了超时时间并已过期,线程才会重新获取锁并继续执行。
  • 锁的影响:与 Thread.sleep() 不同,Object.wait() 会导致线程释放它所持有的对象锁,这样其他线程就有机会获得该锁并执行。
  • 异常处理:同样地,如果线程在等待期间被中断,wait() 方法会抛出 InterruptedException
  • 应用场景:适用于需要线程间协作的场合,比如当一个线程需要等待某个条件成立(如缓冲区中有数据可用)才能继续执行时。
  • 用法

               同步上下文Object.wait() 必须在 synchronized 块内调用,因为它需要当前线程拥有该对象的锁。

               唤醒机制Object.notify() 只会随机唤醒一个等待中的线程,而 Object.notifyAll() 会唤醒所有等待中的线程。

                异常处理:同样需要捕获 InterruptedException

示例
synchronized (sharedResource) {
    while (!condition) { // condition 是一个布尔值,表示等待的条件
        try {
            sharedResource.wait(); // 线程等待,直到被唤醒
        } catch (InterruptedException e) {
            // 重设中断状态
            Thread.currentThread().interrupt();
            System.out.println("Thread was interrupted during wait.");
            return;
        }
    }
    // 执行条件满足后的操作
}

深入理解

  • 锁的管理Thread.sleep() 保持锁,而 Object.wait() 释放锁。这对于线程间协作非常重要,因为 Object.wait() 允许其他线程访问共享资源,而 Thread.sleep() 不允许。
  • 线程间通信Object.wait() 和 Object.notify()/Object.notifyAll() 提供了一种方式让线程间进行通信。一个线程可以等待特定条件,而另一个线程可以在条件满足时通知等待的线程。
  • 死锁预防:由于 Object.wait() 释放锁,所以它可以用来避免死锁。相反,Thread.sleep() 保持锁,如果使用不当,这可能会导致死锁。

注意事项

  • Thread.sleep() 和 Object.wait() 都是静态方法,但 Object.wait() 必须在 synchronized 上下文中调用。
  • 使用 Object.wait() 和 Object.notify()/Object.notifyAll() 时,一定要确保这些方法是在同一个对象上被调用的,否则线程可能永远不会被唤醒。
  • 在处理 InterruptedException 时,通常的做法是恢复中断状态(如果需要的话),以便调用栈中的其他方法能够正确地响应中断。

       你可以根据你的具体需求选择合适的方法来控制线程的行为。如果你只是想简单地暂停线程而不涉及线程间的交互,那么 Thread.sleep() 就足够了;如果你需要实现更复杂的线程间同步逻辑,那么应该考虑使用 Object.wait() 以及相应的 notify()notifyAll() 方法。

标签:Java,Thread,Object,InterruptedException,线程,sleep,wait
From: https://blog.csdn.net/m0_50742275/article/details/143772050

相关文章

  • 26届JAVA 学习日记——Day8
    2024.11.12周二距离上次打卡已经过去了三天,虽然有三天没有学习,但是旅游的过程还是很治愈的。今天开始继续打卡。八股SpringBoot里面有哪些重要的注解?有一个配置相关的注解是哪个?@SpringBootApplicaiton:用于标注主应用程序类,标识一个SpringBoot应用程序的入口点,同时启......
  • Idea2024-java-Maven开发配置
    断断续续用过Idea做一些java的学习,在此记录一下最后的配置过程。安装idea,社区版https://www.jetbrains.com.cn/idea/download/?section=windows安装后,setting检查maven的配置 如果想换Mavan的版本,可以自己下载到本地后,点击“Mavanhomepath”后面的"..."选择你下载并解压后......
  • 《刚刚问世》系列初窥篇-Java+Playwright自动化测试-4-启动浏览器-基于Maven(详细教程)
    1.简介上一篇文章,宏哥已经在搭建的java项目环境中添加jar包实践了如何启动浏览器,今天就在基于maven项目的环境中给小伙伴们或者童鞋们演示一下如何启动浏览器。2.eclipse中新建maven项目1.依次点击eclipse的file-new-other,如下图所示:2.在搜索框输入关键字“maven”,然后......
  • Java复习45(PTA)
    office文档页码打印分数20全屏浏览切换布局作者 黄敏单位 河北科技大学在office软件(word,excel)中,有时只需要打印整个文档中的一部分,就需要用户选择需要打印的页码范围。目前输入的页码范围格式定义为:以逗号分割,可以使用-表示连续页码。例如:1,3,5-9,20。表示需要打印......
  • hnuJava程序设计基础训练-2024
    1. DNA序列(Java)【问题描述】 一个DNA序列由A/C/G/T四个字母的排列组合组成。G和C的比例(定义为GC-Ratio)是序列中G和C两个字母的总的出现次数除以总的字母数目(也就是序列长度)。在基因工程中,这个比例非常重要。因为高的GC-Ratio可能是基因的起始点。给定一个很长的DNA序列,以......
  • Java复习44(PTA)
     单词替换分数10全屏浏览切换布局作者 孙晨霞单位 河北农业大学设计一个对字符串中的单词查找替换方法,实现对英文字符串中所有待替换单词的查找与替换。输入格式:首行输入母字符串,第二行输入查询的单词,第三行输入替换后的单词。输出格式:完成查找替换后的完整......
  • 【多线程奇妙屋】你听说过设计模式吗?软件开发中可全局访问一个对象的设计模式——单例
    本篇会加入个人的所谓鱼式疯言❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言而是理解过并总结出来通俗易懂的大白话,小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.......
  • Java流程控制(三.一)
    publicclassoperator{publicstaticvoidmain(String[]args){//打印九九乘法表for(inti=1;i<10;i++){for(intj=1;j<=i;j++){System.out.print(i+"*"+j+"="+i*j+"\t&q......
  • Java基础面试题
    1.switch的使用intx=2;intresult=0;switch(x){case1:result=result+x;case2:result=result+x*2;case3:result=result+x*3;}System.out.println(result);//返回结果为10//switch语句当case与值不......
  • Java8
    Lambda一、简介Lambda表达式是Java8引入的一种新的语法,它允许你以简洁的方式表示可传递给方法或存储在变量中的代码块。Lambda表达式可以用来替代匿名内部类,使代码更加简洁、易读和易于维护。二、Lambda表达式的基本语法Lambda表达式的语法形式为:(parameters)->expre......