CodeGym /Java 博客 /随机的 /Java 中的 Wait() 方法
John Squirrels
第 41 级
San Francisco

Java 中的 Wait() 方法

已在 随机的 群组中发布
在本文中,我们将了解用于控制线程的wait()方法,以及notify() / notifyAll()方法。这些方法在基类java.lang.Object中定义,因此,Java 中的继承机制将这些方法提供给所有类。也就是说,当您创建自己的类及其对象时,您始终可以调用这些方法。

wait() 和 notify()/notifyAll() 方法如何工作?

  • 等待()。简而言之,此方法释放监视器并将调用线程置于等待状态,直到另一个线程调用 notify () / notifyAll()方法;
  • 通知()。继续之前调用过 wait() 方法的线程的工作;
  • notifyAll()方法恢复之前调用过wait()方法的所有线程。
现在让我们仔细看看wait()方法。Object类包含此方法的三个选项
  • public final native void wait(long timeoutMillis)抛出InterruptedException;它导致当前线程等待直到它被唤醒。通常它会在被通知或中断时发生,或者直到经过一定的实时时间。

  • public final void wait()抛出InterruptedException。我们编写了一个没有参数的方法作为第二个方法并非巧合。事实上,如果你看一下它的代码,它指的是方法的第一个变体,它只有 0L 参数。

  • public final wait (long timeout, int nanos)。导致当前线程等待直到它被唤醒,通常是通过被通知或中断,或者直到一定量的实时已经过去。

wait ()方法旨在挂起调用线程。这是什么意思?这些方法属于类。基于类,您创建一个对象。对象存在于某些线程中。也就是说,对象是在一些线程中创建的。在这个对象工作的线程中,如果你在里面调用wait(),就会导致这个线程停止。对象本身充当一种监视器。它是什么?很明显,您可以创建不同的对象,所有对象都将包含wait()方法。了解哪个对象导致特定线程停止。只要在参数中写入,线程就会停止并等待。然后它就会开始。该线程无法自行启动。要恢复工作,有 notify 和 notifyAll 方法。对notify()notifyAll() 的调用必须运行某个其他线程。使用wait(),您可以停止多个线程,并使用notifyAll()启动所有线程。如果停止了多个线程并调用了notify(),则无法准确判断哪个线程将恢复此方法。如果wait()方法上没有等待线程,那么当notify()notifyAll()被调用。线程只有在当前锁定了特定对象时才能调用该对象的wait()notify()方法。wait()notify()notifyAll()只能从同步代码中调用。

Wait() 方法示例

这里我们有一个最流行的例子来说明该方法的工作原理。假设我们有一家商店、一个生产者和一个消费者。制造商将一些生产产品转移到商店,之后消费者可以取走它们。让制造商必须分别生产8种商品,消费者必须全部购买。但同时仓库中最多只能有6件物品。为了解决这个问题,我们使用wait()notify()方法。让我们定义三个类:MarketManufacturerClientrun()方法中的Manufacturer使用其将 8 种产品添加到Market对象放()方法。客户端在run()方法中循环调用Market对象的get方法来获取这些商品。Market类的 put 和 get 方法是同步的。为了跟踪商品在Market类中的存在,我们检查 item 变量的值。获取产品的 get() 方法只有在至少有一个产品时才会触发因此,在 get 方法中,我们检查产品是否丢失。如果该项目不可用,则调用wait()方法。该方法释放Market对象的监视器并阻塞 get 方法,直到notify()在同一个监视器上调用方法。当在put()方法中添加一个项目并调用notify()时, get()方法获取监视器。之后,我们的客户收到一件物品。为此,将显示一条消息,并减少该项目的值。最后,notify()方法调用向put()方法发出信号以继续。在put()方法中,类似的逻辑起作用,只是现在如果Market中的产品不超过 6 个,put()方法应该起作用。

class Market {

   private int item = 0;

   public synchronized void get() {
       //here we use wait() method
       while (item < 1) {
           try {
               wait();
           }
           catch (InterruptedException e) {
           }
       }
       item--;
       System.out.println("A client has bought 1 item...");
       System.out.println("Items quantity in Market warehouse... " + item);
       notify();
   }

   public synchronized void put() {
       //here we use wait() method when the Warehouse is full
       while (item >= 6) {
           try {
               wait();
           }
           catch (InterruptedException e) {
           }
       }
       item ++;
       System.out.println("Manufacturer has added 1 more item...");
       System.out.println("Now there are " + item + " items in Warehouse" );
       notify();
   }
}

class Manufacturer implements Runnable {

   Market market;

   Manufacturer(Market market) {
       this.market = market;
   }


   public void run() {
       for (int i = 0; i < 8; i++) {
           market.put();
       }
   }
}

class Client implements Runnable {

   Market market;
   Client(Market market) {
       this.market = market;
   }
   public void run() {
       for (int i = 0; i < 8; i++) {
           market.get();
       }
   }
}
//wait() method test class
public class WaitTest {
   public static void main(String[] args) {

       Market market = new Market();
       Manufacturer manufacturer = new Manufacturer(market);
       Client client = new Client(market);
       new Thread(manufacturer).start();
       new Thread(client).start();
   }
}
在这里,在get()方法中使用wait(),我们正在等待制造商添加新项目。而在添加之后,我们调用notify(),就好像说 Warehouse 上有一个地方空闲了你可以添加更多。在put()方法中,使用wait() ,我们正在等待Warehouse上的空间释放。空间空闲后,我们添加项目,notify()启动线程,客户端可以拿起项目。这是我们程序的输出:
制造商又添加了 1 件商品...现在仓库里有 1 件商品 制造商又添加了 1 件商品...现在仓库里有 2 件商品 制造商又添加了 1 件商品...现在仓库里有 3 件商品 制造商有添加了 1 个项目... 现在仓库中有 4 个项目 制造商又添加了 1 个项目... 现在仓库中有 5 个项目 制造商又添加了 1 个项目... 现在仓库中有 6 个项目 客户已购买1 件商品... 市场仓库中的商品数量... 5 客户购买了 1 件商品... 市场仓库中的商品数量... 4 客户购买了 1 件商品... 市场仓库中的商品数量... 3客户已购买 1 件商品... 市场仓库中的商品数量... 2 客户已购买 1 件商品... 市场仓库中的商品数量... 1 客户已购买 1 件商品... 市场仓库中的商品数量...0 制造商又添加了 1 件商品... 现在仓库中有 1 件商品 制造商又添加了 1 件商品... 现在仓库中有 2 件商品 客户购买了 1 件商品... 市场仓库中的商品数量... 1 客户购买了 1 件商品...市场仓库中的商品数量...0 退出代码为 0 的流程已完成
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION