CodeGym/Java blog/Véletlen/Wait() metódus Java nyelven
John Squirrels
Szint
San Francisco

Wait() metódus Java nyelven

Megjelent a csoportban
Ebben a cikkben megvizsgáljuk a wait() metódust a szál vezérléséhez, valamint a notify() / notifyAll() metódusokat. Ezek a metódusok a java.lang.Object alaposztályban vannak definiálva , és ennek megfelelően a Java-ban található öröklési mechanizmusok abszolút minden osztály számára biztosítják ezeket a metódusokat. Ez azt jelenti, hogy amikor létrehozza saját osztályát és objektumait, mindig hívhatja ezeket a metódusokat.

Hogyan működik a wait() és notify()/notifyAll() metódus?

  • várj () . röviden, ez a metódus felszabadítja a monitort, és a hívó szálat várakozási állapotba helyezi, amíg egy másik szál meg nem hívja a notify() / notifyAll() metódust;
  • értesít() . Folytatja annak a szálnak a munkáját, amelynek a wait() metódusát korábban meghívták;
  • A notifyAll() metódus folytatja az összes olyan szálat, amelyhez korábban meghívták a wait() metódust.
Most nézzük meg közelebbről a wait() metódust. Az Object osztály három lehetőséget tartalmaz ehhez a metódushoz:
  • public final native void wait(long timeoutMillis) dob InterruptedException ; Ez arra készteti az aktuális szálat, hogy megvárja, amíg felébred. Általában ez úgy történik, hogy értesítést kapnak vagy megszakítják, vagy amíg egy bizonyos valós idő el nem telik.

  • public final void wait() az InterruptedException -t dobja . Nem véletlenül írtunk egy paraméter nélküli metódust másodiknak. Valójában, ha megnézzük a kódját, akkor a metódus első változatára utal, csak a 0L argumentum van benne.

  • nyilvános végső várakozás (hosszú időtúllépés, int nanos) . Arra készteti az aktuális szálat, hogy megvárja, amíg felébred, általában értesítés vagy megszakítás miatt, vagy amíg egy bizonyos valós idő eltelik.

A wait() metódus célja a hívó szál felfüggesztése. Mit jelent? Ezek a metódusok az osztályba tartoznak. Az osztály alapján létrehoz egy objektumot. Egyes szálakban objektumok léteznek. Vagyis bizonyos szálakban objektumok jönnek létre. Abban a szálban, amelyben ez az objektum működik, ha meghívja benne a wait()- ot, ez azt eredményezi, hogy ez a szál leáll. Maga az objektum egyfajta monitorként működik. Mi az? Nyilvánvaló, hogy különböző objektumokat hozhat létre, és mindegyik tartalmazni fogja a wait()módszer. Meg kell érteni, hogy melyik objektum okozta egy adott szál leállítását. A szál leáll, és addig vár, amíg a paraméterben meg van írva. És akkor kezdődik. Ez a szál nem indulhat el magától. A munka folytatásához az értesítés és a notifyAll módszerek állnak rendelkezésre. A notify() vagy notifyAll() hívásnak más szálat kell lejátszania. A wait() segítségével több szálat is leállíthat, és az összes szálat a notifyAll() paranccsal indíthatja el . Ha több szálat leállítottak, és a notify() meghívásra került, nem lehet pontosan megmondani, hogy melyik szál folytatja ezt a metódust. Ha nincsenek várakozó szálak a wait() metóduson, akkor nem történik semmi, amikor notify() vagyA notifyAll() meghívásra kerül. Egy szál csak akkor hívhatja meg a wait() vagy notify() metódusokat egy adott objektumon, ha az adott objektum jelenleg zárolva van. A wait() , notify() és notifyAll() csak szinkronizált kódból hívható meg.

Wait() metódus példa

Itt van az egyik legnépszerűbb példa, amely bemutatja a módszer működését. Tegyük fel, hogy van boltunk, termelőnk és fogyasztónk. A gyártó néhány termelési terméket átad az üzletbe, majd a fogyasztó átveheti azokat. A gyártónak 8 árut kell előállítania, a fogyasztónak meg kell vásárolnia mindet. De ugyanakkor legfeljebb 6 cikk lehet egyszerre a raktárban. A probléma megoldására a wait() és notify() metódusokat használjuk . Határozzuk meg három osztályt: Piac , Gyártó és Ügyfél . A Run () metódus gyártója 8 terméket ad hozzá a Market objektumhoz a saját használatávalput() metódus. A ciklusban lévő run() metódusban lévő kliens meghívja a Market objektum get metódusát, hogy megszerezze ezeket a termékeket. A Market osztály put és get metódusai szinkronizálva vannak. A Market osztályban lévő áruk jelenlétének nyomon követéséhez ellenőrizzük a cikkváltozó értékét. A get() metódus egy termék megszerzésére csak akkor aktiválódik, ha van legalább egy termék. Ezért a get metódusban ellenőrizzük, hogy hiányzik-e a termék. Ha az elem nem elérhető, a wait() metódus meghívásra kerül. Ez a metódus felszabadítja a Market objektum monitorját, és blokkolja a get metódust, amíg a notify()metódus ugyanazon a monitoron kerül meghívásra. Amikor hozzáadunk egy elemet a put() metódushoz, és a notify() meghívásra kerül, a get() metódus megkapja a monitort. Ezt követően ügyfelünk árut kap. Ehhez egy üzenet jelenik meg, és az elem értéke csökken. Végül a notify() metódushívás jelzi a put() metódusnak a folytatást. A put() metódusban hasonló logika működik, csak most a put() metódusnak kell működnie, ha nincs több mint 6 termék a Marketen .
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();
   }
}
Itt a get() metódusban a wait()-t használva arra várunk, hogy a Gyártó új elemet adjon hozzá. És a hozzáadás után meghívjuk a notify() -t , mintha azt mondanánk, hogy egy hely szabaddá vált a Raktárban , és továbbiakat is hozzáadhat. A put() metódusban a wait() használatával várjuk a hely felszabadulását a Raktáron . A hely felszabadulása után hozzáadjuk az elemet, a notify() elindítja a szálat, és az Ügyfél átveheti az elemet. Íme a programunk eredménye:
A gyártó hozzáadott még 1 terméket... Jelenleg 1 termék van a Raktárban A gyártó hozzáadott még 1 terméket... Jelenleg 2 termék van a raktárban A gyártó hozzáadott még 1 terméket... Jelenleg 3 termék van a raktárban A gyártó hozzáadott még 1 terméket... Jelenleg 4 cikk van a raktárban A gyártó hozzáadott még 1 terméket... Jelenleg 5 cikk van a raktárban A gyártó hozzáadott még 1 terméket... Jelenleg 6 termék van a raktárban Egy ügyfél vásárolt 1 cikk... Cikkmennyiség a Market raktárban... 5 Egy ügyfél 1 cikket vásárolt... Cikkmennyiség a Market raktárban... 4 Egy ügyfél 1 terméket vásárolt... Cikkmennyiség a Piaci raktárban... 3 Egy ügyfél 1 terméket vásárolt... Cikkek mennyisége a Market raktárában... 2 Egy ügyfél 1 terméket vásárolt... Cikkek mennyisége a Market raktárában... 1 Egy ügyfél 1 terméket vásárolt... Cikkek mennyisége a Market raktárában ...0 A gyártó hozzáadott még 1 terméket... Jelenleg 1 cikk van a Raktárban A gyártó még 1 terméket adott hozzá... Jelenleg 2 cikk van a Raktárban Egy ügyfél 1 terméket vásárolt... Cikkek mennyisége a Piaci raktárban... 1 Egy ügyfél 1 terméket vásárolt... Cikkek mennyisége a piaci raktárban... 0 A folyamat befejeződött 0 kilépési kóddal
Hozzászólások
  • Népszerű
  • Új
  • Régi
Hozzászólás írásához be kell jelentkeznie
Ennek az oldalnak még nincsenek megjegyzései