Java中wait()和sleep()区别小结

 更新时间:2025年10月01日 11:39:23   作者:IT橘子皮  
在Java多线程编程中,wait()和 sleep()是两个常用的线程控制方法,但它们在工作原理、使用场景和效果上有显著区别,本文就来详细的介绍一下两者的差异,感兴趣的可以了解一下

在 Java 多线程编程中,wait()sleep()是两个常用的线程控制方法,但它们在工作原理、使用场景和效果上有显著区别。以下是两者的主要差异:

1. 所属类与基本性质

  • sleep()​​:是 Thread类的静态方法,可以直接通过 Thread.sleep()调用,用于让当前线程暂停执行指定的时间。
  • wait()​​:是 Object类的实例方法,必须通过对象实例调用(如 obj.wait()),主要用于线程间的通信与协调。

2. 锁的行为差异(核心区别)

  • sleep()​​:

    • 不释放锁​:当线程调用 sleep()时,即使线程进入休眠状态,它仍然持有已经获取的任何对象锁。
    • 其他线程无法获取被休眠线程持有的锁,导致同步代码块或方法无法被并发执行。
  • wait()​​:

    • 释放锁​:调用 wait()会使线程释放当前持有的对象锁,并进入该对象的等待池(waiting pool)。
    • 其他线程可以获取该对象的锁并执行同步代码。

3. 使用场景

  • sleep()​​:

    • 用于让线程暂停执行一段时间,不涉及线程间通信。
    • 典型场景:模拟延迟、定时任务、控制执行节奏等。
  • wait()​​:

    • 用于线程间协作,通常与 notify()/notifyAll()配合使用。
    • 典型场景:生产者-消费者模式、线程交替执行等需要条件等待的场景。

4. 唤醒机制

  • sleep()​​:

    • 自动唤醒:线程会在指定的时间结束后自动恢复就绪状态。
  • wait()​​:

    • 需要被动唤醒:必须由其他线程调用同一对象的 notify()notifyAll()方法才能唤醒。
    • 也支持带超时的 wait(long timeout),超时后会自动唤醒。

5. 调用前提条件

  • sleep()​​:

    • 可以在任何地方调用,不需要在同步代码块中。
  • wait()​​:

    • 必须在同步代码块或同步方法中调用​(即必须先获取对象的监视器锁)。
    • 否则会抛出 IllegalMonitorStateException异常。

6. 异常处理

两者都会抛出 InterruptedException

  • 当线程在休眠或等待期间被其他线程中断时触发。
  • 都需要捕获或声明抛出该异常。

7. 线程状态变化

  • sleep()​​:

    • 使线程进入 ​TIMED_WAITING​(带超时)或 ​WAITING​(无超时)状态。
  • wait()​​:

    • 使线程进入 ​WAITING​(无超时)或 ​TIMED_WAITING​(带超时)状态,并释放锁。

代码示例对比

sleep() 示例(不释放锁)

synchronized (lock) {
    System.out.println("线程获取锁,开始sleep");
    try {
        Thread.sleep(2000); // 休眠2秒,不释放lock锁
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("线程sleep结束");
}
// 其他线程必须等待sleep结束后才能获取锁

wait() 示例(释放锁)

synchronized (lock) {
    System.out.println("线程获取锁,开始wait");
    try {
        lock.wait(); // 释放lock锁,进入等待队列
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("线程被唤醒,重新获取锁");
}
// 其他线程可以在wait期间获取lock锁

总结对比表

特性sleep()wait()
所属类Thread类的静态方法Object类的实例方法
锁释放不释放锁释放锁
使用场景线程暂停执行线程间通信与协作
唤醒方式自动唤醒(时间到)notify()/notifyAll()唤醒
调用前提无需同步环境必须在 synchronized中调用
异常InterruptedExceptionInterruptedException+ IllegalMonitorStateException
典型用途定时、延迟生产者-消费者、条件等待

关键结论

  1. 锁行为​:sleep()持有锁不放,wait()释放锁——这是最本质的区别。
  2. 协作机制​:wait()/notify()是 Java 多线程协作的基础机制,而 sleep()只是单纯的线程暂停。
  3. 使用规范​:误用 wait()(如不在同步块中调用)会导致运行时异常,而 sleep()的使用相对简单。

在实际开发中,应根据是否需要线程间协作来选择使用哪个方法:若只是需要延迟,用 sleep();若需要等待某个条件满足(如资源就绪),则用 wait()

到此这篇关于Java中wait()和sleep()区别小结的文章就介绍到这了,更多相关Java wait()和sleep()区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java String字符串的常用使用方法

    Java String字符串的常用使用方法

    String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表示,本文给大家介绍Java String字符串的常用使用方法,感兴趣的朋友一起看看吧
    2025-04-04
  • Hibernate单表操作实例解析

    Hibernate单表操作实例解析

    这篇文章主要介绍了Hibernate单表操作实例解析,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • java实现五子棋大战

    java实现五子棋大战

    这篇文章主要为大家详细介绍了java实现五子棋大战,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Vue结合Springboot实现用户列表单页面(前后端分离)

    Vue结合Springboot实现用户列表单页面(前后端分离)

    本文主要介绍了Vue结合Springboot实现用户列表单页面,可以实现简单的查询,删除,修改,和添加用户信息功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • SpringBoot登录认证前后端实现方案:SpringBoot + Mybatis + JWT(图文实例)

    SpringBoot登录认证前后端实现方案:SpringBoot + Mybatis +&

    本文展示如何在Spring生态系统中整合IOC/DI、MyBatis、MD5加密、Session/Cookie管理、JWT令牌和拦截器,以实现一个企业级的认证方案,前端使用HTML/CSS/JavaScript/JQuery,后端使用SpringBoot+MyBatis+JWT,通过统一返回结果封装和图形验证码,提高了API的可维护性和安全性
    2025-10-10
  • Spring boot中限制 Mybatis SQL日志的大字段输出问题

    Spring boot中限制 Mybatis SQL日志的大字段输出问题

    文章介绍Springboot中MyBatis SQL日志因大字段输出导致日志膨胀及JVM内存问题,建议通过Logback或Log4j2自定义Converter/Filter实现参数截断或脱敏,或调整日志级别限制调试信息,本文给大家介绍Spring boot中限制Mybatis SQL日志的大字段输出问题,感兴趣的朋友一起看看吧
    2025-10-10
  • IntelliJ IDEA配置java环境及解决IDEA不能直接运行单个JAVA文件的问题

    IntelliJ IDEA配置java环境及解决IDEA不能直接运行单个JAVA文件的问题

    这篇文章主要介绍了IntelliJ IDEA配置java环境及解决IDEA不能直接运行单个JAVA文件的问题,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • spring注入配置文件属性到java类

    spring注入配置文件属性到java类

    这篇文章主要为大家介绍了spring注入配置文件属性到java类实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • springboot + vue 实现递归生成多级菜单(实例代码)

    springboot + vue 实现递归生成多级菜单(实例代码)

    这篇文章主要介绍了springboot + vue 实现递归生成多级菜单,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-12-12
  • java开发线上事故理解RocketMQ异步精髓

    java开发线上事故理解RocketMQ异步精髓

    这篇文章主要介绍了java开发线上事故理解RocketMQ异步精髓
    2022-07-07

最新评论