wait()和sleep()
wait和sleep
wait()
和 sleep()
都是 Java 中用于控制线程行为的方法,但它们的作用和用法有所不同。以下是两者的主要区别:
1. 调用方式
-
wait()
:-
wait()
是一个实例方法,它只能在同步块或同步方法中调用,通常在synchronized
代码块内使用。 -
wait()
会让当前线程释放持有的锁并进入等待状态,直到它被其他线程通过notify()
或notifyAll()
唤醒。 -
它只能用于对象上,而
sleep()
是一个Thread
类的静态方法,不依赖于对象锁。
-
-
sleep()
:-
sleep()
是一个静态方法,直接通过Thread.sleep()
调用。 -
sleep()
会让当前线程暂停执行指定的时间,期间不会释放锁,因此其他线程无法执行同一个锁保护的代码。
-
2. 目的和作用
-
wait()
-
wait()
的目的是使线程进入“等待”状态,通常在多个线程之间进行协作时使用。例如,生产者-消费者模型中,一个线程在等待某个条件满足时可能会调用wait()
,等待其他线程通过notify()
或notifyAll()
唤醒它。 -
在
wait()
被调用时,线程会释放对象锁,允许其他线程访问该锁。
-
-
sleep()
:-
sleep()
的目的是让线程暂停执行一段指定的时间,而不需要依赖任何条件。它常用于需要延迟执行或者暂停线程一段时间的情况。 -
在
sleep()
被调用时,线程不会释放锁。即使其他线程试图获取该锁,它也会继续阻塞。
-
3. 线程的行为
-
wait()
:-
线程进入等待状态,直到被其他线程通过
notify()
或notifyAll()
唤醒。 -
线程在等待期间可以释放对象锁。
-
线程的状态会从“运行”状态变成“等待”状态(
WAITING
),直到被唤醒。
-
-
sleep()
:-
线程会休眠指定的时间,然后自动恢复执行。
-
线程不会释放对象锁,因此,如果其他线程想要获取该锁,它们会被阻塞。
-
线程的状态会从“运行”状态变成“睡眠”状态(
TIMED_WAITING
)直到指定时间结束。
-
4. 使用场景
-
wait()
:-
用于线程间的通信(如生产者-消费者模式、读写锁等)。
-
在某些条件满足之前,线程需要等待,例如等待资源、等待某个值的变化等。
-
-
sleep()
:-
用于需要延时或控制线程的执行速率的场景。
-
常用于例如定时任务、节流控制、延迟处理等,不需要与其他线程协作。
-
5. 异常处理
-
wait()
:-
由于
wait()
方法会抛出InterruptedException
,所以需要进行异常处理或抛出异常。
-
-
sleep()
:-
也会抛出
InterruptedException
,如果线程在休眠期间被中断,它会抛出该异常,因此也需要进行异常处理。
-
6. 示例
-
wait()
示例:public class WaitNotifyExample {private static final Object lock = new Object();public static void main(String[] args) {Thread thread1 = new Thread(() -> {synchronized (lock) {try {System.out.println("Thread1: Waiting");lock.wait(); // 线程进入等待状态System.out.println("Thread1: Notified");} catch (InterruptedException e) {e.printStackTrace();}}});Thread thread2 = new Thread(() -> {synchronized (lock) {System.out.println("Thread2: Doing work and notifying");lock.notify(); // 唤醒等待中的线程}});thread1.start();thread2.start();} }
-
sleep()
示例:public class SleepExample {public static void main(String[] args) {Thread thread = new Thread(() -> {try {System.out.println("Thread: Sleeping");Thread.sleep(2000); // 让线程暂停2秒System.out.println("Thread: Woke up after sleep");} catch (InterruptedException e) {e.printStackTrace();}});thread.start();} }
总结:
-
wait()
用于线程间的协调,线程通过释放锁进入等待状态,直到其他线程调用notify()
或notifyAll()
唤醒它。 -
sleep()
用于让线程暂停执行一段时间,线程会在指定时间后自动恢复,不会释放锁。