Java中的wait()方法用于线程间的协作,其作用是将当前线程挂起,等待其他线程唤醒。
语法格式
public final void wait() throws InterruptedException
public final native void wait(long timeout) throws InterruptedException
public final void wait(long timeout, int nanos) throws InterruptedException
wait()方法的用法
wait()方法必须要在synchronized块中调用,否则会抛出IllegalMonitorStateException异常。当线程进入synchronized块后,如果调用wait()方法,则当前线程会被挂起,直到其他线程调用notify()或notifyAll()方法唤醒该线程。
在调用wait()方法后,当前线程释放所持有的锁,其他线程才有机会获取该锁。
wait()方法可以重载,可以指定等待的最长时间,如果时间到达后仍未被其他线程唤醒,会自动唤醒当前线程。
wait()方法的示例
示例1:使用wait()和notify()协同线程
下面的示例展示了如何使用wait()和notify()协同两个线程。
public class WaitAndNotifyTest {
public static void main(String[] args) {
final Object lock = new Object();
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
System.out.println(Thread.currentThread().getName() + "开始等待...");
lock.wait();
System.out.println(Thread.currentThread().getName() + "等待结束...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "线程A");
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + "开始唤醒等待线程...");
lock.notify();
System.out.println(Thread.currentThread().getName() + "完成唤醒等待线程...");
}
}
}, "线程B");
threadA.start();
threadB.start();
}
}
输出结果:
线程A开始等待...
线程B开始唤醒等待线程...
线程B完成唤醒等待线程...
线程A等待结束...
在本例中,线程A等待线程B发出notify(),线程B发出notify()之后,线程A才会继续运行。
示例2:使用wait()和notifyAll()协同多个线程
下面的示例展示了如何使用wait()和notifyAll()协同多个线程。
public class WaitAndNotifyAllTest {
public static void main(String[] args) {
final Object lock = new Object();
Thread[] threads = new Thread[5];
for (int i = 0; i < 5; i++) {
threads[i] = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
System.out.println(Thread.currentThread().getName() + "开始等待...");
lock.wait();
System.out.println(Thread.currentThread().getName() + "等待结束...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "线程" + (i + 1));
threads[i].start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + "开始唤醒等待线程...");
lock.notifyAll();
System.out.println(Thread.currentThread().getName() + "完成唤醒等待线程...");
}
}
}, "线程A");
threadA.start();
}
}
输出结果:
线程1开始等待...
线程2开始等待...
线程3开始等待...
线程4开始等待...
线程5开始等待...
线程A开始唤醒等待线程...
线程A完成唤醒等待线程...
线程1等待结束...
线程2等待结束...
线程3等待结束...
线程4等待结束...
线程5等待结束...
在本例中,多个线程在同一个锁lock上等待,线程A发出notifyAll()之后,所有线程都被唤醒,最终所有线程都完成了等待。