wait()
和 sleep()
是多线程编程中的两个常用方法,它们虽然都能暂停线程的执行,但在实现上有明显的区别。下面详细解释它们的定义、用法和主要区别:
wait() 方法
-
定义:
wait()
是Object
类中的一个方法,用于暂停当前线程的执行,并将它放入等待池中,直到另一个线程调用同一对象的notify()
或notifyAll()
方法来唤醒该线程。 -
使用场景: 通常用于线程间通信,即一个线程等待某个条件满足,而另一个线程负责通知(或唤醒)等待的线程。
-
关键点:
- 必须在同步块或同步方法中调用
wait()
。 - 调用
wait()
时,线程会释放持有的对象锁。 - 一直等到另一个线程调用
notify()
或notifyAll()
,或者被中断。
- 必须在同步块或同步方法中调用
synchronized (lock) {
while (!condition) {
lock.wait();
}
// 执行其他操作
}
sleep() 方法
-
定义:
sleep()
是Thread
类中的一个静态方法,用于使当前线程暂停执行指定的时间,以毫秒和纳秒为单位。 -
使用场景: 用于简单地让线程休眠一段时间,不涉及线程间的通信。
-
关键点:
- 可以在任何地方调用
sleep()
,不需要在同步块中。 - 调用
sleep()
时,线程不会释放持有的对象锁。 - 指定时间后自动恢复执行,也可以被中断。
- 可以在任何地方调用
try {
Thread.sleep(1000); // 当前线程休眠1000毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
区别总结
特性/属性 | wait() | sleep() |
---|---|---|
所属类 | Object | Thread |
是否需要同步块 | 是 | 否 |
是否释放锁 | 是 | 否 |
是否可以被唤醒 | 是(通过 notify() 或 notifyAll() ) | 否(只能通过等待时间结束或被中断) |
用途 | 线程间通信,等待某个条件 | 暂停当前线程执行指定时间 |
示例代码
以下是一个示例代码,展示了如何使用 wait()
和 notify()
进行线程间通信,以及如何使用 sleep()
进行线程休眠:
public class WaitNotifyExample {
private static final Object lock = new Object();
public static void main(String[] args) {
Thread waitingThread = new Thread(() -> {
synchronized (lock) {
try {
System.out.println("Waiting thread: Waiting for the lock to be released...");
lock.wait();
System.out.println("Waiting thread: Got notified and resumed execution!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread notifyingThread = new Thread(() -> {
try {
Thread.sleep(2000); // 模拟一些工作需要两秒钟
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock) {
System.out.println("Notifying thread: Acquired the lock and notifying...");
lock.notify();
}
});
waitingThread.start();
notifyingThread.start();
}
}
在这个示例中:
waitingThread
会在获取到lock
后调用wait()
,进入等待状态并释放lock
。notifyingThread
会先休眠 2 秒,然后获取到lock
并调用notify()
来唤醒等待的线程。
总结
wait()
用于线程间的协调和通信,必须在同步块内调用,并且会释放锁。sleep()
用于简单地暂停线程的执行,但不会释放锁。