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.
-
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.
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
GO TO FULL VERSION