wait
和sleep
都是Java中用于线程控制的方法,但它们在使用、功能和上下文中有显著的不同。以下是它们之间的主要区别:
- 所属类 :
-
sleep
是Thread
类的静态方法。 -
wait
是Object
类的方法。
- 使用要求 :
-
sleep
方法可以在任何地方调用,不需要在同步块或同步方法中。 -
wait
方法必须在同步块或同步方法中调用,否则会抛出IllegalMonitorStateException
异常。
- 锁的释放与获取 :
-
sleep
方法在调用期间不会释放线程持有的锁,线程在休眠结束后会继续执行,并持有原有的锁。 -
wait
方法在调用时会释放线程持有的对象锁,进入等待状态,直到其他线程调用同一对象的notify()
或notifyAll()
方法,该线程才会重新获取锁并继续执行。
- 唤醒方式 :
-
sleep
方法在指定的时间结束后自动恢复执行,或者可以通过调用interrupt()
方法来中断并抛出InterruptedException
异常。 -
wait
方法必须被其他线程通过notify()
或notifyAll()
方法显式唤醒,或者等待指定的超时时间结束。
- 用途 :
-
sleep
方法通常用于让线程暂停执行一段时间,例如用于定时任务或控制线程的执行频率。 -
wait
方法通常用于线程间的通信和协作,例如生产者-消费者问题,其中一个线程在条件不满足时会等待,直到另一个线程发出通知。
示例代码
public class SleepWaitExample {
private static final Object lock = new Object();
public static void main(String[] args) {
Thread sleepThread = new Thread(() -> {
try {
System.out.println("Sleeping for 5 seconds...");
Thread.sleep(5000); // 暂停5秒
System.out.println("Awake!");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread waitThread = new Thread(() -> {
synchronized (lock) {
try {
System.out.println("Waiting for 5 seconds...");
lock.wait(); // 等待5秒
System.out.println("Awake!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
sleepThread.start();
waitThread.start();
}
}
在这个示例中,sleepThread
使用Thread.sleep()
方法暂停5秒,而waitThread
使用lock.wait()
方法等待5秒。注意waitThread
必须在同步块中调用,并且需要lock
对象来同步等待和唤醒。
总结
-
sleep :用于线程休眠指定时间,不释放锁,适用于定时任务和控制线程执行频率。
-
wait :用于线程等待其他线程的通知或超时,释放锁,适用于线程间通信和协作。
根据具体的应用场景和需求,可以选择合适的方法来实现线程的暂停和唤醒。