在Java中,wait()和yield()都是用于线程控制的方法,但它们的作用和使用场景完全不同。以下是它们的详细区别:
1. wait()方法
(1) 定义
wait()是Object类的方法,用于线程间通信。
- 调用
wait()的线程会释放锁并进入等待状态,直到其他线程调用notify()或notifyAll()唤醒它,或者等待超时。
(2) 使用场景
- 用于多线程协作,通常与
notify()或notifyAll()配合使用。
- 常用于生产者-消费者模型或线程间的条件等待。
(3) 特点
- 释放锁:调用
wait()的线程会释放持有的锁。
- 需要同步块:
wait()必须在synchronized块或方法中调用,否则会抛出IllegalMonitorStateException。
- 唤醒机制:线程可以通过
notify()、notifyAll()或超时唤醒。
(4) 示例
1 2 3 4 5 6
| synchronized (lock) { while (conditionNotMet) { lock.wait(); } }
|
2. yield()方法
(1) 定义
yield()是Thread类的静态方法,用于提示线程调度器当前线程愿意让出CPU资源。
- 调用
yield()的线程会从运行状态进入就绪状态,让其他线程有机会执行。
(2) 使用场景
- 用于线程调度的优化,避免某个线程长时间占用CPU。
- 通常用于测试或调试,实际开发中较少使用。
(3) 特点
- 不释放锁:调用
yield()的线程不会释放持有的锁。
- 不保证让出CPU:
yield()只是一个提示,具体是否让出CPU由线程调度器决定。
- 不进入阻塞状态:线程从运行状态进入就绪状态,而不是阻塞状态。
(4) 示例
1 2 3 4 5 6
| public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + " - " + i); Thread.yield(); } }
|
3. wait()和yield()的区别
| 特性 |
wait() |
yield() |
| 所属类 |
Object类 |
Thread类 |
| 作用 |
线程等待,释放锁 |
线程让出CPU,不释放锁 |
| 锁的释放 |
释放锁 |
不释放锁 |
| 调用位置 |
必须在synchronized块或方法中调用 |
可以在任何地方调用 |
| 线程状态 |
从运行状态进入等待状态(WAITING) |
从运行状态进入就绪状态(RUNNABLE) |
| 唤醒机制 |
需要notify()、notifyAll()或超时唤醒 |
无需唤醒,由线程调度器决定 |
| 使用场景 |
线程间通信,条件等待 |
线程调度优化,避免长时间占用CPU |
| 是否抛出异常 |
可能抛出InterruptedException |
不会抛出异常 |
4. 使用注意事项
(1) wait()的注意事项
- 必须在
synchronized块或方法中调用。
- 通常与
while循环结合使用,避免虚假唤醒(Spurious Wakeup)。
- 调用
wait()后,线程会释放锁,其他线程可以进入同步块。
(2) yield()的注意事项
yield()只是一个提示,具体是否让出CPU由线程调度器决定。
- 不能依赖
yield()来控制线程执行的顺序。
- 在实际开发中,
yield()的使用场景较少,通常用于调试或测试。
5. 示例对比
(1) wait()示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class SharedResource { private boolean ready = false;
public synchronized void produce() { ready = true; notify(); }
public synchronized void consume() throws InterruptedException { while (!ready) { wait(); } System.out.println("Consumed"); } }
|
(2) yield()示例
1 2 3 4 5 6 7 8 9
| class Worker implements Runnable { @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " - " + i); Thread.yield(); } } }
|
总结
wait():用于线程间通信,释放锁并等待条件满足,通常与notify()或notifyAll()配合使用。
yield():用于线程调度优化,提示让出CPU,但不释放锁,实际开发中较少使用。
理解wait()和yield()的区别及其适用场景,有助于更好地编写多线程程序。