Sleep与Wait的区别

一、一句话先记住(非常重要)

sleep 是 Thread 的"休息",不释放锁;
wait 是 Object 的"等待通知",会释放锁。


二、sleep vs wait 对比表(核心差异)

对比点 sleep() wait()
所属类 Thread Object
是否释放锁 ❌ 不释放 ✅ 释放
使用位置 任意地方 必须在 synchronized 中
唤醒方式 时间到自动醒 notify / notifyAll
是否需要捕获异常 是(InterruptedException) 是
用途 让线程暂停一段时间 线程间通信

三、代码对比 ①:sleep 不释放锁

示例:sleep 导致别的线程进不来

java 复制代码
public class SleepDemo {

    private static final Object lock = new Object();

    public static void main(String[] args) {

        new Thread(() -> {
            synchronized (lock) {
                System.out.println("线程A拿到锁");
                try {
                    Thread.sleep(3000); // 不释放锁
                } catch (InterruptedException e) {}
                System.out.println("线程A结束");
            }
        }).start();

        new Thread(() -> {
            synchronized (lock) {
                System.out.println("线程B拿到锁");
            }
        }).start();
    }
}

运行结果(重点理解)

bash 复制代码
线程A拿到锁
(3 秒)
线程A结束
线程B拿到锁

原因解析(关键)

  • sleep() 不会释放 synchronized 的锁

  • 线程A睡觉了,但仍然霸占着锁

  • 线程B只能干等

👉 这就是 sleep = 线程自己睡觉,不管别人


四、代码对比 ②:wait 会释放锁

示例:wait + notify 正确的线程通信

java 复制代码
public class WaitDemo {

    private static final Object lock = new Object();

    public static void main(String[] args) {

        new Thread(() -> {
            synchronized (lock) {
                System.out.println("线程A拿到锁");
                try {
                    lock.wait(); // 释放锁,进入等待
                } catch (InterruptedException e) {}
                System.out.println("线程A被唤醒");
            }
        }).start();

        new Thread(() -> {
            synchronized (lock) {
                System.out.println("线程B拿到锁");
                lock.notify(); // 唤醒等待的线程
            }
        }).start();
    }
}

运行结果

java 复制代码
线程A拿到锁
线程B拿到锁
线程A被唤醒

原因解析(重点)

  • wait() 会:

    1. 释放锁

    2. 当前线程进入等待队列

  • notify():

    • 只是通知

    • 线程A必须 重新抢到锁 才能继续执行

👉 这就是 wait = 放下锁,等别人叫你


五、为什么 wait 必须在 synchronized 中?

错误示例(面试常问):

java 复制代码
lock.wait(); // ❌ 直接报异常

报什么错?

java 复制代码
IllegalMonitorStateException

原因(必须会说)

因为 wait/notify 是 对象级别的线程通信机制

只有持有该对象的锁,才能调用它们。


六、底层记忆法(非常好记)

用生活比喻

Java 现实
synchronized 占用会议室
sleep 在会议室里睡觉(不让别人进)
wait 离开会议室等通知
notify 叫人回来开会

七、面试标准回答模板(直接背)

sleep 是 Thread 类的方法,用于让线程休眠一段时间,但不会释放锁;

wait 是 Object 类的方法,用于线程间通信,会释放锁,必须在 synchronized 中使用,通常配合 notify 或 notifyAll 使用。


八、你是否真的学会了?自测 3 问

1️⃣ sleep 会不会释放锁?

2️⃣ wait 能不能单独调用?

3️⃣ notify 之后线程一定马上执行吗?

相关推荐
GIS数据转换器6 小时前
地下空间综合管廊运营管理平台
大数据·开发语言·人工智能·经验分享·perl
猿究院_夏燊10 小时前
Spring Bean 生命周期
java·后端·spring
Wang's Blog11 小时前
Java 项目实战: 交友项目:登录链路回顾与今日任务地图
java·开发语言·状态模式·交友
信誓旦旦的程序猿11 小时前
【Python量化实战宝典 #08】可转债与债券接口手册:转股价·溢价率·纯债价值(Python 可跑)
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
砚底藏山河11 小时前
python量化:行情数据回溯
java·开发语言·python·金融·maven
今年下半年11 小时前
AI智能体项目实战记录(02):初始化 Python 项目
开发语言·人工智能·python·fastapi
Jlzn888812 小时前
华东电芯分选通道数怎么配才不堵线
java·人工智能·架构·自动化·制造
Williamtym12 小时前
PickGo Lab实践:用浏览器、Python和MCP串起机器人搬运仿真
开发语言·python·机器人
香吧香12 小时前
GRPC连接机制---长连接分析
java·网络与传输协议
DongQiShanRen12 小时前
六根硬件映射(四):归属澄清、两处不一致与卷十一总表
开发语言·人工智能·算法·rust·哈希算法·集成学习