Java中的wait()方法及示例
线程间通信是同步线程可以使用wait()、notify() 和notifyAll() 方法相互通信的一种方式。 wait() 方法是Java.lang.Object 类的一部分。当调用wait() 方法时,调用线程停止执行直到notify() 或notifyAll() 方法被其他线程调用。
句法:
public final void wait() throws InterruptedException
例外
- InterruptedException – 如果任何线程在当前线程等待通知之前或期间中断了当前线程。
- IllegalMonitorStateException – 如果当前线程不是对象监视器的所有者。
在职的:
- 在Java中,同步方法和块一次只允许一个线程获取资源锁。因此,当线程调用 wait() 方法时,它会放弃对该资源的锁定并进入睡眠状态,直到某个其他线程进入同一个监视器并调用 notify() 或 notifyAll() 方法。
- 调用 notify() 仅唤醒一个线程,调用 notifyAll() 唤醒同一对象上的所有线程。调用这两个方法不会放弃对资源的锁定,而是使用 wait() 方法唤醒已发送到睡眠状态的线程。
- sleep() 方法和 wait() 方法之间的一个很大区别是 sleep() 方法使线程休眠指定的时间,而 wait() 使线程休眠直到调用 notify() 和 notifyAll() 。
在下面提到的代码中,我们创建了一个类GunFight ,其中包含一个成员变量 bullets,该变量初始化为 40,以及两个方法 fire() 和 reload()。 fire() 方法会发射传递给它的子弹数量,直到子弹变为 0,当子弹变为 0 时,它会调用 wait() 方法,这会导致调用线程休眠并在 reload() 方法增加时释放对象上的锁子弹 40 并调用 notify() 方法唤醒等待线程。
Java
// Java program to demonstrate the use of wait() method
class GunFight {
private int bullets = 40;
// This method fires the number of bullets that are
// passed it. When the bullet in magazine becomes zero,
// it calls the wait() method and releases the lock.
synchronized public void fire(int bulletsToBeFired)
{
for (int i = 1; i <= bulletsToBeFired; i++) {
if (bullets == 0) {
System.out.println(i - 1
+ " bullets fired and "
+ bullets + " remains");
System.out.println(
"Invoking the wait() method");
try {
wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(
"Continuing the fire after reloading");
}
bullets--;
}
System.out.println(
"The firing process is complete");
}
// reload() increases the bullets by 40 everytime it is
// invoked and calls the notify() method which wakes up
// the thread that was sent to sleep using wait() inside
// of fire() method
synchronized public void reload()
{
System.out.println(
"Reloading the magazine and resuming "
+ "the thread using notify()");
bullets += 40;
notify();
}
}
public class WaitDemo extends Thread {
public static void main(String[] args)
{
GunFight gf = new GunFight();
// Creating a new thread and invoking
// our fire() method on it
new Thread() {
@Override public void run() { gf.fire(60); }
}.start();
// Creating a new thread and invoking
// our reload method on it
new Thread() {
@Override public void run() { gf.reload(); }
}.start();
}
}
输出
40 bullets fired and 0 remains
Invoking the wait() method
Reloading the magazine and resuming the thread using notify()
Continuing the fire after reloading
The firing process is complete