Java中Thread.sleep和wait的核心差异在于锁的处理:Thread.sleep不释放已持有的锁,仅实现线程暂停;而Object.wait会释放当前对象锁,并进入等待队列,直到被notify、超时或中断,用于线程间协作。

在Java中,
Thread.sleep()
Object.wait()
Thread.sleep()
Object.wait()
要深入理解
Thread.sleep
Object.wait
Thread.sleep(long millis)
Thread.sleep()
Thread
Thread.sleep(long millis)
synchronized
sleep()
synchronized
sleep()
Object.wait()
wait(long millis)
wait(long millis, int nanos)
Object.wait()
Object
wait()
立即学习“Java免费学习笔记(深入)”;
wait()
sleep()
wait()
notify()
notifyAll()
wait(long millis)
InterruptedException
wait()
synchronized
wait()
IllegalMonitorStateException
wait()
总结核心差异: | 特性 |
Thread.sleep()
Object.wait()
Thread
Object
synchronized
wait()
notify()
notifyAll()
public class SleepAndWaitDifference {
private static final Object lock = new Object();
private static boolean conditionMet = false;
public static void main(String[] args) throws InterruptedException {
// 示例1: Thread.sleep 不释放锁
Thread sleepThread = new Thread(() -> {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + ": 获取到锁,准备sleep...");
try {
Thread.sleep(2000); // 暂停2秒,但不释放锁
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(Thread.currentThread().getName() + ": sleep结束,释放锁。");
}
}, "SleepThread");
Thread blockingThread = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + ": 尝试获取锁...");
synchronized (lock) { // 会被SleepThread阻塞
System.out.println(Thread.currentThread().getName() + ": 成功获取到锁。");
}
}, "BlockingThread");
sleepThread.start();
// 确保SleepThread先获取锁
Thread.sleep(100);
blockingThread.start();
sleepThread.join();
blockingThread.join();
System.out.println("--- Sleep 示例结束 ---\n");
// 示例2: Object.wait 释放锁
Thread waitingThread = new Thread(() -> {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + ": 获取到锁,准备wait...");
while (!conditionMet) { // 使用while循环防止虚假唤醒
try {
lock.wait(); // 释放锁并等待
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
System.out.println(Thread.currentThread().getName() + ": 被唤醒,条件满足,继续执行,释放锁。");
}
}, "WaitingThread");
Thread notifyingThread = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + ": 准备通知...");
try {
Thread.sleep(1000); // 模拟一些工作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
synchronized (lock) { // 必须获取到锁才能notify
conditionMet = true;
System.out.println(Thread.currentThread().getName() + ": 改变条件,并调用notifyAll()...");
lock.notifyAll(); // 唤醒所有等待的线程
}
}, "NotifyingThread");
waitingThread.start();
Thread.sleep(100); // 确保waitingThread先进入wait状态
notifyingThread.start();
waitingThread.join();
notifyingThread.join();
System.out.println("--- Wait/Notify 示例结束 ---");
}
}运行上述代码,你会清晰地看到
BlockingThread
SleepThread
NotifyingThread
WaitingThread
最核心的差异在于它们对对象监视器锁(monitor lock)的处理方式。
Thread.sleep()
sleep()
sleep()
sleep()
相比之下,
Object.wait()
notify()
notifyAll()
此外,
wait()
sleep()
notify()
notifyAll()
sleep()
选择
Thread.sleep
Object.wait()
选择 Thread.sleep()
Thread.sleep()
sleep()
选择 Object.wait()
notify()
notifyAll()
Object.wait()
wait()
wait()
notify()
wait()
notify()
BlockingQueue
CountDownLatch
wait()
notify()
true
关键的决策点在于: 你暂停线程的目的是什么?是为了单纯的时间延迟,还是为了等待某个条件的改变?如果涉及到共享资源和线程间的条件依赖,并且需要释放锁以便其他线程能够修改这些条件,那么
wait()
notify()
sleep()
Object.wait()
常见陷阱:
不在 synchronized
wait()
wait()
notify()
notifyAll()
IllegalMonitorStateException
// 错误示例 // lock.wait(); // 如果不在synchronized(lock)块中,会抛出IllegalMonitorStateException
虚假唤醒(Spurious Wakeups): 线程可能在没有收到
notify()
notifyAll()
if (condition)
// 错误示例 (可能导致虚假唤醒后条件不满足却继续执行)
// if (!conditionMet) {
// lock.wait();
// }notify()
notifyAll()
notify()
notify()
notify()
wait()
死锁: 如果
notify()
notifyAll()
wait()
信号丢失: 如果
notify()
wait()
notify()
wait()
最佳实践:
始终在 while
wait()
synchronized (lock) {
while (!conditionMet) { // 必须使用while循环
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
// 处理中断逻辑,例如重新设置条件,或者退出循环
return;
}
}
// 条件满足,继续执行
}总是使用 notifyAll()
notify()
notifyAll()
notifyAll()
wait()
确保 notify()
notifyAll()
notify()
synchronized
synchronized (lock) {
conditionMet = true; // 改变条件
lock.notifyAll(); // 唤醒等待线程
}优先使用 java.util.concurrent
BlockingQueue
CountDownLatch
Semaphore
CyclicBarrier
ReentrantLock
Condition
wait()
notify()
ArrayBlockingQueue
LinkedBlockingQueue
wait()
notify()
ReentrantLock
newCondition()
Condition
await()
signal()
signalAll()
Object.wait()
notify()
notifyAll()
遵循这些最佳实践,可以帮助你编写出更可靠、更易于维护的并发代码。在大多数情况下,如果不是在编写底层的并发库,你都应该考虑优先使用
java.util.concurrent
以上就是Java中Thread.sleep与wait区别的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号