În acest articol, ne vom uita la metoda wait() pentru a controla firul și la metodele notify() / notifyAll() . Aceste metode sunt definite în clasa de bază java.lang.Object și, în consecință, mecanismele de moștenire care sunt în Java oferă aceste metode pentru absolut toate clasele. Adică, atunci când vă creați propria clasă și obiectele acesteia, puteți apela oricând aceste metode.
Cum funcționează metodele wait() și notify()/notifyAll()?
- așteptați() . pe scurt, această metodă eliberează monitorul și pune firul care apelează într-o stare de așteptare până când un alt fir apelează metoda notify() / notifyAll() ;
- notifică () . Continuă munca unui fir a cărui metodă wait() a fost apelată anterior;
- Metoda notifyAll() reia toate firele de execuție cărora li sa apelat anterior metoda wait() .
-
public final nativ void wait(long timeoutMillis) aruncă InterruptedException ; Determină firul curent să aștepte până când este trezit. De obicei, se întâmplă prin a fi notificat sau întrerupt, sau până când a trecut o anumită perioadă de timp real.
-
public final void wait() aruncă InterruptedException . Nu întâmplător am scris o metodă fără parametri ca a doua. De fapt, dacă te uiți la codul său, se referă la prima variantă a metodei, are doar argumentul 0L.
-
așteptare finală publică (timeout lung, int nanos) . Determină firul curent să aștepte până când este trezit, de obicei prin notificare sau întrerupere, sau până când a trecut o anumită perioadă de timp real.
Exemplu de metodă Wait().
Aici avem unul dintre cele mai populare exemple care ilustrează modul în care funcționează metoda. Să presupunem că avem un magazin, un producător și un consumator. Producătorul transferă unele produse de producție în magazin, după care consumatorul le poate lua. Lăsați producătorul să producă 8 bunuri, respectiv, consumatorul trebuie să le cumpere pe toate. Dar, în același timp, în depozit nu pot fi mai mult de 6 articole în același timp. Pentru a rezolva această problemă, folosim metodele wait() și notify() . Să definim trei clase: piață , producător și client . Metoda Manufacturer in the run() adaugă 8 produse la obiectul Market utilizând- ometoda put() . Clientul din metoda run() într-o buclă apelează metoda get a obiectului Market pentru a obține aceste produse. Metodele put și get ale clasei Market sunt sincronizate. Pentru a urmări prezența mărfurilor în clasa Market , verificăm valoarea variabilei articol. Metoda get() pentru obținerea unui produs ar trebui să se declanșeze numai dacă există cel puțin un produs. Prin urmare, în metoda get, verificăm dacă produsul lipsește. Dacă articolul nu este disponibil, este apelată metoda wait() . Această metodă eliberează monitorul obiectului Market și blochează metoda get până când notify()metoda este apelată pe același monitor. Când un element este adăugat în metoda put() și este apelat notify() , metoda get() primește monitorul. După aceea, clientul nostru primește un articol. Pentru a face acest lucru, este afișat un mesaj, iar valoarea articolului este decrementată. În cele din urmă, apelul metodei notify() semnalează metodei put() să continue. În metoda put() funcționează o logică similară, doar că acum metoda put() ar trebui să funcționeze dacă nu există mai mult de 6 produse pe piață .
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();
}
}
Aici, folosind wait() în metoda get() , așteptăm ca Producătorul să adauge un nou articol. Și după adăugare, sunăm notify() , ca și cum ar fi să spunem că un loc a devenit liber în Warehouse și puteți adăuga mai multe. În metoda put() , folosind wait() , așteptăm eliberarea spațiului pe Warehouse . După ce spațiul este liber, adăugăm articolul, notify() începe firul și Clientul poate ridica articolul. Iată rezultatul programului nostru:
Producătorul a adăugat încă 1 articol... Acum există 1 articole în Warehouse Producătorul a adăugat încă 1 articol... Acum există 2 articole în Warehouse Producătorul a adăugat încă 1 articol... Acum există 3 articole în Warehouse Producătorul a adăugat a adăugat încă 1 articol... Acum sunt 4 articole în Warehouse Producătorul a adăugat încă 1 articol... Acum sunt 5 articole în Warehouse Producătorul a adăugat încă 1 articol... Acum există 6 articole în Warehouse Un client a cumpărat 1 articol... Cantitatea articolelor din depozitul Market... 5 Un client a cumpărat 1 articol... Cantitatea articolelor din depozitul Market... 4 Un client a cumpărat 1 articol... Cantitatea articolelor din depozitul Market... 3 Un client a cumpărat 1 articol... Cantitatea articolelor din depozitul Market... 2 Un client a cumpărat 1 articol... Cantitatea articolelor din depozitul Market... 1 Un client a cumpărat 1 articol... Cantitatea articolelor din depozitul Market ...0 Producătorul a adăugat încă 1 articol... Acum există 1 articole în Depozit Producătorul a adăugat încă 1 articol... Acum există 2 articole în Depozit Un client a cumpărat 1 articol... Cantitatea de articole în depozitul Market... 1 Un client a cumpărat 1 articol... Cantitate articole în depozitul Market... 0 Proces terminat cu codul de ieșire 0
GO TO FULL VERSION