CodeGym/Java блог/Случаен/Метод Wait() в Java
John Squirrels
Ниво
San Francisco

Метод Wait() в Java

Публикувано в групата
В тази статия ще разгледаме метода wait() за управление на нишката и методите notify() / notifyAll() . Тези методи са дефинирани в базовия клас java.lang.Object и съответно механизмите за наследяване, които са в Java предоставят тези методи на абсолютно всички класове. Тоест, когато създавате свой собствен клас и неговите обекти, винаги можете да извиквате тези методи.

Как работят методите wait() и notify()/notifyAll()?

  • изчакай() . накратко, този метод освобождава монитора и поставя извикващата нишка в състояние на изчакване, докато друга нишка извика метода notify() / notifyAll() ;
  • notify() . Продължава работата на нишка, чийто метод wait() е бил извикан преди това;
  • Методът notifyAll() възобновява всички нишки, които преди това са извикали своя метод wait() .
Сега нека разгледаме по-отблизо метода wait() . Класът Object съдържа три опции за този метод:
  • public final native void wait(long timeoutMillis) хвърля InterruptedException ; Това кара текущата нишка да изчака, докато се събуди. Обикновено това се случва, когато бъдете уведомени or прекъснати, or докато не изтече определено време в реално време.

  • public final void wait() хвърля InterruptedException . Неслучайно като втори написахме метод без параметри. Всъщност, ако погледнете неговия code, той се отнася до първия вариант на метода, има само аргумента 0L.

  • публично окончателно изчакване (дълъг период на изчакване, int nanos) . Кара текущата нишка да изчака, докато бъде събудена, обикновено чрез известяване or прекъсване, or докато не изтече определено време в реално време.

Методът wait() е предназначен да спре извикващата нишка. Какво означава? Тези методи принадлежат към класа. Въз основа на класа създавате обект. Обектите съществуват в някои нишки. Тоест обектите се създават в някои нишки. В нишката, в която работи този обект, ако извикате wait() в нея, това ще доведе до факта, че тази нишка ще спре. Самият обект действа като вид монитор. Какво е? Ясно е, че можете да създавате различни обекти и всички те ще съдържат wait()метод. Има разбиране кой обект е причинил спирането на определена нишка. Нишката спира и ще чака толкова дълго, колкото е записано в параметъра. И тогава ще започне. Тази нишка не може да стартира сама. За да възобновите работата, има методи notify и notifyAll. Извикването на notify() or notifyAll() трябва да изпълни друга нишка. С wait() можете да спрете множество нишки и да стартирате всички нишки с notifyAll() . Ако няколко нишки са спрени и notify() е извикан, не е възможно да се каже точно коя нишка ще възобнови този метод. Ако няма чакащи нишки на метода wait() , тогава нищо не се случва, когато notify() ornotifyAll() се извиква. Нишката може да извика методите wait() or notify() на определен обект само ако в момента има заключване на този обект. wait() , notify() и notifyAll() трябва да се извикват само от синхронизиран code.

Пример за метод Wait().

Тук имаме един от най-популярните примери, който илюстрира How работи методът. Да кажем, че имаме магазин, производител и потребител. Производителят прехвърля някои продукти от производството в магазина, след което потребителят може да ги вземе. Нека производителят трябва да произведе 8 стоки, съответно потребителят трябва да ги купи всичките. Но в същото време не повече от 6 артикула могат да бъдат в склада едновременно. За да разрешим този проблем, използваме методите wait() и notify() . Нека дефинираме три класа: пазар , производител и клиент . Производителят в метода run() добавя 8 продукта към обекта Market , използвайки свояput() метод. Клиентът в метода run() в цикъл извиква метода get на обекта Market , за да получи тези продукти. Методите put и get на пазарния клас са синхронизирани. За да проследим наличието на стоки в пазарния клас, проверяваме стойността на променливата на артикула. Методът get() за получаване на продукт трябва да се активира само ако има поне един продукт. Следователно в метода get проверяваме дали продуктът липсва. Ако елементът не е наличен, се извиква методът wait() . Този метод освобождава монитора на обекта Market и блокира метода get, докато notify()методът се извиква на същия монитор. Когато се добави елемент в метода put() и се извика notify() , методът get() получава монитора. След това нашият клиент получава артикул. За да направите това, се показва съобщение и стойността на елемента се намалява. И накрая, извикването на метода notify() сигнализира на метода put() да продължи. В метода put() работи подобна логика, само че сега методът put() трябва да работи, ако няма повече от 6 продукта на пазара .
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();
   }
}
Тук, използвайки wait() в метода get() , ние чакаме производителя да добави нов артикул. И след като добавим, извикваме notify() , сякаш за да кажем, че едно място е станало свободно в Warehouse и можете да добавите още. В метода put() , използвайки wait() , ние чакаме освобождаването на място в Warehouse . След като мястото е свободно, добавяме артикула, notify() стартира нишката и клиентът може да вземе артикула. Ето резултата от нашата програма:
Производителят добави още 1 артикул... Сега има 1 артикула в склада Производителят добави още 1 артикул... Сега има 2 артикула в склада Производителят добави още 1 артикул... Сега има 3 артикула в склада Производителят има добави още 1 артикул... Сега има 4 артикула в склада. Производителят добави още 1 артикул... Сега има 5 артикула в склада. Производителят добави още 1 артикул... Сега има 6 артикула в склада. Клиент е купил 1 артикул... Количество артикули в склад Market... 5 Клиент е закупил 1 артикул... Количество артикули в склад Market... 4 Клиент е закупил 1 артикул... Количество артикули в склад Market... 3 Клиент е закупил 1 артикул... Количество артикули в склад на Market... 2 Клиент е закупил 1 артикул... Количество на артикули в склад на Market... 1 Клиент е закупил 1 артикул... Количество на артикули в склад на Market ...0 Производителят е добавил още 1 артикул... Сега има 1 артикула в склада Производителят е добавил още 1 артикул... Сега има 2 артикула в склада Клиент е закупил 1 артикул... Количество на артикулите в склада на Market... 1 Клиент е закупил 1 артикул... Количество на артикулите в склада на Market... 0 Процесът приключи с изходен code 0
Коментари
  • Популярен
  • Нов
  • Стар
Трябва да сте влезли, за да оставите коментар
Тази страница все още няма коментари