Java中的wait()方法是多线程编程中的一个重要同步机制,它允许一个线程在某个对象上进行等待,直到另一个线程通知它,以下是关于如何使用Java中的wait()方法的详细说明。

wait()方法的基本使用
wait()方法定义在Object类中,因此所有的Java对象都可以调用它,以下是wait()方法的基本使用方式:
synchronized(object) {
object.wait();
}
这里,object是一个对象引用,它必须具有同步方法或代码块,当线程调用wait()方法时,它会释放对object的锁,并进入等待状态,当另一个线程调用object.notify()或object.notifyAll()方法时,等待的线程会唤醒。
wait()方法的参数
wait()方法可以接受一个可选的long参数,表示等待的时间(以毫秒为单位),如果这个参数是正数,线程将等待指定的时间,如果在这段时间内被唤醒,则继续执行;如果时间到了还没有被唤醒,线程将抛出InterruptedException。
synchronized(object) {
object.wait(1000); // 等待1000毫秒
}
wait()方法的注意事项
-
必须捕获异常:当线程在等待状态中被唤醒时,如果等待时指定了超时时间,并且超时了,线程会抛出
InterruptedException,调用wait()方法的线程应该捕获这个异常。
-
释放锁:当线程调用
wait()方法时,它会自动释放当前持有的锁,这是非常重要的,因为如果线程在等待时不释放锁,其他线程将无法访问同步代码块或方法。 -
不可中断的等待:如果线程在调用
wait()方法时不指定超时时间,那么它将一直等待,直到被另一个线程显式唤醒,在这种情况下,线程无法响应中断。
经验案例
假设有一个生产者-消费者问题,其中生产者线程生产数据,消费者线程消费数据,以下是一个使用wait()方法的简单示例:
class Data {
private int number;
private boolean flag = false;
public synchronized void produce() throws InterruptedException {
while (flag) {
this.wait();
}
number = 100;
flag = true;
this.notifyAll();
}
public synchronized void consume() throws InterruptedException {
while (!flag) {
this.wait();
}
System.out.println("Number: " + number);
flag = false;
this.notifyAll();
}
}
在这个例子中,生产者线程在flag为true时等待,消费者线程在flag为false时等待,当生产者生产数据后,flag变为true,并唤醒所有等待的线程;当消费者消费数据后,flag变为false,并唤醒所有等待的线程。

FAQs
Q1:为什么在调用wait()方法后需要释放锁?
A1:因为wait()方法会使当前线程释放对象的锁,这样其他线程才能进入同步代码块或方法,如果线程不释放锁,其他线程将无法访问同步代码块或方法,从而导致死锁。
Q2:wait()方法和sleep()方法有什么区别?
A2:wait()方法是线程同步的一部分,它会导致当前线程释放锁,并进入等待状态,直到被另一个线程唤醒,而sleep()方法只是让当前线程暂停执行一段时间,但它不会释放锁。wait()方法通常用于线程间的通信,而sleep()方法用于线程的暂停。
文献权威来源
《Java核心技术卷II:高级特性》作者:Cay S. Horstmann 《Java并发编程实战》作者:Brian Goetz、Tim Peierls、Joshua Bloch、Joseph Bowbeer、David Holmes、Brian Goetz 《深入理解Java虚拟机》作者:周志明