Java多线程中wait()与sleep()方法的区别
wait()和sleep()在Java多线程编程中都能使线程暂停执行,但它们有本质区别:
1. 所属类不同
- wait(): 属于Object类的方法,所有Java对象都可调用
- sleep(): 属于Thread类的静态方法,只能通过Thread类或线程对象调用
2. 锁资源处理不同
- wait(): 释放当前持有的对象锁,允许其他线程获取该锁
- sleep(): 不释放锁资源,即使线程休眠,仍然保持对锁的占用
3. 调用位置要求
- wait(): 必须在synchronized同步块或同步方法中调用,否则会抛出IllegalMonitorStateException
- sleep(): 可以在任何地方调用,无需在同步上下文中
4. 唤醒机制不同
- wait(): 需要通过notify()/notifyAll()方法或中断来唤醒
- sleep(): 时间到后自动唤醒,或者可以通过interrupt()方法提前唤醒
5. 使用场景不同
- wait(): 用于线程间协作与通信,实现线程间的等待/通知机制
- sleep(): 主要用于使当前线程暂停执行指定的时间,不涉及线程间通信
6. 异常处理不同
- wait(): 抛出InterruptedException和IllegalMonitorStateException
- sleep(): 只抛出InterruptedException
代码示例
wait()方法示例:
public class WaitExample {
public static void main(String[] args) {
final Object lock = new Object();
Thread thread1 = new Thread(() -> {
synchronized (lock) {
System.out.println("线程1获取到锁");
try {
System.out.println("线程1调用wait()方法");
lock.wait(); // 释放锁,等待被唤醒
System.out.println("线程1被唤醒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread thread2 = new Thread(() -> {
try {
Thread.sleep(1000); // 确保线程1先执行
synchronized (lock) {
System.out.println("线程2获取到锁");
lock.notify(); // 唤醒等待的线程
System.out.println("线程2通知完成");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread1.start();
thread2.start();
}
}
sleep()方法示例:
public class SleepExample {
public static void main(String[] args) {
final Object lock = new Object();
Thread thread1 = new Thread(() -> {
synchronized (lock) {
System.out.println("线程1获取到锁");
try {
System.out.println("线程1调用sleep()方法");
Thread.sleep(3000); // 不释放锁,只是让线程休眠
System.out.println("线程1休眠结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread thread2 = new Thread(() -> {
try {
Thread.sleep(1000); // 确保线程1先执行
System.out.println("线程2尝试获取锁");
synchronized (lock) {
System.out.println("线程2获取到锁"); // 只有在线程1释放锁后才能执行到这里
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread1.start();
thread2.start();
}
}
总结来说,wait()主要用于线程间协作,会释放锁并等待通知;而sleep()主要用于控制线程执行节奏,不释放锁资源。在实际多线程编程中,理解并正确使用这两个方法对于实现高效的线程同步至关重要