当前位置: 首页 > web >正文

JAVA:深入理解 wait() 和 sleep() 的区别与实战

1、简述

在进行 Java 并发编程时,wait()sleep() 是两个非常常见的方法。很多初学者常常将它们混淆,本文将从底层原理、使用语义、对象归属、场景应用等方面深入剖析二者的区别,并通过实际代码加深理解。

在这里插入图片描述


2、基本定义

Thread.sleep(long millis)

  • 属于 Thread 类的静态方法
  • 用于让当前线程进入休眠状态指定时间
  • 不释放任何对象的锁

Object.wait(long millis)

  • 属于 Object 类的实例方法
  • 当前线程在获取某个对象锁后可以调用它
  • 调用后线程进入等待状态,并释放对象锁

关键区别对比

特性sleep()wait()
所属类ThreadObject
是否释放锁❌ 不释放锁✅ 释放锁
是否需要同步块❌ 不需要✅ 必须在同步代码块中(synchronized)调用
用途暂停当前线程线程间通信与协作
唤醒方式时间到自动唤醒notify()notifyAll() 手动唤醒
抛出异常InterruptedExceptionInterruptedException

3、实战代码示例

示例 1:sleep 不释放锁的表现

public class SleepLockDemo {public static void main(String[] args) {final Object lock = new Object();Thread t1 = new Thread(() -> {synchronized (lock) {System.out.println("T1 acquired lock, sleeping 5s...");try {Thread.sleep(5000); // 不释放锁} catch (InterruptedException e) {e.printStackTrace();}System.out.println("T1 done.");}});Thread t2 = new Thread(() -> {synchronized (lock) {System.out.println("T2 acquired lock.");}});t1.start();try { Thread.sleep(100); } catch (Exception e) {}t2.start();}
}
输出:
T1 acquired lock, sleeping 5s...
(T2 阻塞中,等待锁)
T1 done.
T2 acquired lock.
分析:
  • T1 使用 sleep 睡眠时 不会释放锁
  • T2 一直阻塞在 synchronized (lock)

示例 2:wait 会释放锁

public class WaitNotifyDemo {public static void main(String[] args) {final Object lock = new Object();Thread t1 = new Thread(() -> {synchronized (lock) {System.out.println("T1 acquired lock, calling wait()...");try {lock.wait(); // 会释放锁System.out.println("T1 resumed.");} catch (InterruptedException e) {e.printStackTrace();}}});Thread t2 = new Thread(() -> {try { Thread.sleep(1000); } catch (Exception e) {}synchronized (lock) {System.out.println("T2 acquired lock, notifying...");lock.notify(); // 唤醒 T1}});t1.start();t2.start();}
}
输出:
T1 acquired lock, calling wait()...
T2 acquired lock, notifying...
T1 resumed.
分析:
  • wait() 会释放锁,T2 得以获取锁并调用 notify()
  • notify() 唤醒等待中的 T1

4、常见面试问题总结

问题解答
wait()sleep() 有什么根本区别?wait() 用于线程通信,释放锁;sleep() 用于线程暂停,不释放锁
wait() 能不能放在同步块外面用?❌ 不能,必须持有对象锁,否则抛出 IllegalMonitorStateException
sleep() 会不会影响锁?❌ 不会,线程持有的锁不会释放
wait() 会自动恢复吗?❌ 不会,必须被其他线程 notify()notifyAll()

5、总结

项目sleep()wait()
ThreadObject
用途暂停当前线程线程间协调与通信
是否释放锁
是否依赖同步是(必须加锁)
唤醒方式自动时间唤醒手动唤醒(notify)

使用建议

✅ 使用 sleep() 场景:

  • 模拟延迟(定时任务、重试)
  • 轮询等待(不推荐,性能差)

✅ 使用 wait() 场景:

  • 多线程协作模型(生产者-消费者)
  • 阻塞线程等待某条件达成
http://www.xdnf.cn/news/13885.html

相关文章:

  • 78Qt窗口_QStatusBar的基本使用
  • centos6.5 老旧系统编译glib-2.58.3.tar.bz2
  • mesh转solid freecad
  • OpenCV——图像基本操作(三)
  • 【开发常用命令】:docker常用命令
  • preload、preconnect、prefetch 的作用
  • day033-备份服务rsync
  • Pytorch中view函数详解和工程实战示例
  • docker compose的变量使用说明
  • 【完整源码+数据集+部署教程】太阳能板灰尘检测系统源码和数据集:改进yolo11-LVMB
  • 京津冀城市群13城市空间权重0-1矩阵
  • Rosetta 2介绍
  • 第三章支线七 ·路由边境 · 多页世界的穿梭之术
  • 【MicronTech】eMMC 部件编号解析
  • flutter 的lottie执行一次动画后关闭
  • Windows美化终端、安装wsl和docker
  • Python Day49
  • 一阶/二阶Nomoto模型(野本模型)为何“看不到”船速对回转角速度/角加速度的影响?
  • 智慧管廊数字化运维管理平台
  • 规则引擎rule-engine v1.0实现解释(一)-规则,执行,容器
  • Vue3中组件Ref打印Proxy(Object)与defineExpose的深度解析
  • navicat 有免费版了,navicat 官方免费版下载
  • vue2项目开发中遇到的小问题
  • Goland使用手册(1)
  • 【亲测有效】MybatisPlus中MetaObjectHandler自动填充字段失效
  • Tess4J:基于 Java 的 OCR 解决方案
  • php反序列化漏洞学习
  • 电脑PC端使用的备忘录记事软件推荐哪个
  • 【3】使用TRAE AI在已有框架中新增页面并实现切换的痛苦经历
  • boa 找不到动态库的解决办法: