一、wait方法的概述
public final void wait() throws InterruptedException
wait方法是Object类中的一个方法,用于让当前线程进入等待状态,直到其他线程调用该对象的notify或notifyAll方法才可以唤醒它。调用wait方法必须使用在synchronized中,由于这个原因,wait方法只能够被在同步块内或者同步方法中调用,否则会抛出IllegalMonitorStateException。在调用wait方法时,线程会释放掉它所持有的锁,这样其他线程就可以进入到同步块或者同步方法中执行相应的代码。
二、wait方法的用法
wait方法常用于实现线程的互斥机制,通过wait和notify的配合使用,不同的线程可以协调运行。
wait方法的一般用法是:
- 获取要运行的线程对象
- 在同步块中调用线程对象的wait方法
- 在另一个线程中调用线程对象的notify或者notifyAll方法,通知要运行的线程唤醒
下面是一个使用wait和notify实现生产者消费者模型的示例代码:
public class ProducerConsumerExample {
public static void main(String[] args) {
Product product = new Product();
new ProducerThread(product).start();
new ConsumerThread(product).start();
}
static class ProducerThread extends Thread {
private Product product;
ProducerThread(Product product) {
this.product = product;
}
@Override
public void run() {
while (true) {
synchronized (product) {
while (product.getCount() >= Product.MAX_COUNT) {
try {
product.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
product.incrementCount();
System.out.println("生产了1个产品,当前产品数量为:" + product.getCount());
product.notifyAll();
}
}
}
}
static class ConsumerThread extends Thread {
private Product product;
ConsumerThread(Product product) {
this.product = product;
}
@Override
public void run() {
while (true) {
synchronized (product) {
while (product.getCount() <= 0) {
try {
product.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
product.decrementCount();
System.out.println("消费了1个产品,当前产品数量为:" + product.getCount());
product.notifyAll();
}
}
}
}
static class Product {
private int count;
static final int MAX_COUNT = 10;
int getCount() {
return count;
}
void incrementCount() {
count++;
}
void decrementCount() {
count--;
}
}
}
三、wait方法的注意事项
1、wait方法会释放锁
在执行wait方法之前,线程必须先获得锁,wait方法会释放该锁,使得其他线程可以获得这个锁。当wait方法返回后,当前线程又会重新获取这个锁。
2、wait方法可能会出现虚假唤醒
虚假唤醒是指,当一个线程调用了wait方法进入了等待状态,即使没有其他线程调用notify或notifyAll方法也有可能会被唤醒。对于此问题,可以在while循环中使用wait方法,循环条件为需要等待的条件。
3、线程调用interrupt方法可以中断wait方法
当一个线程在等待状态中,另一个线程调用了它的interrupt方法时,这个线程会抛出InterruptedException异常,从而退出等待状态。因此,在使用wait方法时要注意捕获InterruptedException异常。
四、总结
wait方法是实现线程等待和通知的重要手段,可以通过配合notify或notifyAll实现线程的协作运行。但是在使用wait方法时,需要考虑到线程的安全性,防止出错。