I denne artikel vil vi se på wait() -metoden til at styre tråden og notify() / notifyAll()- metoderne. Disse metoder er defineret i basisklassen java.lang.Object , og følgelig leverer de nedarvningsmekanismer, der er i Java, disse metoder til absolut alle klasser. Det vil sige, at når du opretter din egen klasse og dens objekter, kan du altid kalde disse metoder.
Hvordan fungerer metoderne wait() og notify()/notifyAll()?
- vent() . kort sagt frigiver denne metode monitoren og sætter den kaldende tråd i ventetilstand, indtil en anden tråd kalder notify() / notifyAll() metoden;
- underrette() . Fortsætter arbejdet med en tråd, hvis wait()-metode tidligere blev kaldt;
- notifyAll()- metoden genoptager alle tråde, der tidligere har fået deres wait()- metode kaldt.
-
public final native void wait (lang timeoutMillis) kaster InterruptedException ; Det får den aktuelle tråd til at vente, indtil den er vækket. Normalt sker det ved at blive underrettet eller afbrudt, eller indtil der er gået en vis mængde realtid.
-
public final void wait() kaster InterruptedException . Det er ikke tilfældigt, at vi skrev en metode uden parametre som den anden. Faktisk, hvis du ser på dens kode, refererer den til den første variant af metoden, den har bare 0L-argumentet.
-
offentlig endelig ventetid (lang timeout, int nanos) . Får den aktuelle tråd til at vente, indtil den vækkes, typisk ved at blive underrettet eller afbrudt, eller indtil en vis mængde realtid er gået.
Wait() metode eksempel
Her har vi et af de mest populære eksempler, der illustrerer, hvordan metoden fungerer. Lad os sige, at vi har en butik, en producent og en forbruger. Producenten overfører nogle produktionsprodukter til butikken, hvorefter forbrugeren kan tage dem. Lad producenten være nødt til at producere henholdsvis 8 varer, forbrugeren skal købe dem alle. Men samtidig må der ikke være mere end 6 varer på lageret på samme tid. For at løse dette problem bruger vi metoderne wait() og notify() . Lad os definere tre klasser: Marked , Producent og Kunde . Metoden Manufacturer in the run() tilføjer 8 produkter til Market- objektet ved hjælp af densput() metode. Klienten i run() -metoden i en loop kalder get-metoden for Market- objektet for at få disse produkter. Put and get-metoderne i Market- klassen er synkroniserede. For at spore tilstedeværelsen af varer i markedsklassen tjekker vi værdien af varevariablen. Get () -metoden til at få et produkt bør kun udløses, hvis der er mindst ét produkt. Derfor tjekker vi i get-metoden, om produktet mangler. Hvis elementet ikke er tilgængeligt, kaldes wait()- metoden. Denne metode frigiver Market -objektets monitor og blokerer get-metoden, indtil notify()metode kaldes på den samme skærm. Når et element tilføjes i put()- metoden og notify() kaldes, henter get()- metoden monitoren. Derefter modtager vores kunde en vare. For at gøre dette vises en meddelelse, og varens værdi nedsættes. Til sidst signalerer notify()- metodekaldet put()- metoden for at fortsætte. I put()- metoden virker lignende logik, kun nu burde put()- metoden virke, hvis der ikke er mere end 6 produkter på markedet .
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();
}
}
Her, ved at bruge wait() i get()- metoden, venter vi på, at producenten tilføjer et nyt element. Og efter tilføjelse ringer vi notify() , som for at sige, at ét sted er blevet ledigt på Lageret , og du kan tilføje flere. I put()- metoden, ved hjælp af wait() , venter vi på frigivelse af plads på Warehouse . Når pladsen er ledig, tilføjer vi varen, notify() starter tråden og klienten kan hente varen. Her er outputtet af vores program:
Producenten har tilføjet 1 vare mere... Nu er der 1 varer i lageret Producenten har tilføjet 1 vare mere... Nu er der 2 varer i lageret Producenten har tilføjet 1 vare mere... Nu er der 3 varer i lageret Producenten har tilføjet 1 vare mere... Nu er der 4 varer i Warehouse Manufacturer har tilføjet 1 varer mere... Nu er der 5 varer i Warehouse Manufacturer har tilføjet 1 varer mere... Nu er der 6 varer i Warehouse En kunde har købt 1 vare... Antal varer i markedslager... 5 En kunde har købt 1 vare... Antal varer i markedslager... 4 En kunde har købt 1 vare... Antal varer i markedslager... 3 En kunde har købt 1 vare... Antal varer i Markedslager... 2 En kunde har købt 1 vare... Antal varer i Markedslager... 1 En kunde har købt 1 vare... Vareantal i Markedslager ...0 Producent har tilføjet 1 vare mere... Nu er der 1 varer i lageret Producenten har tilføjet 1 varer mere... Nu er der 2 varer på lageret En kunde har købt 1 vare... Antal varer i markedslageret... 1 En kunde har købt 1 vare... Vareantal på markedslager... 0 Processen afsluttet med udgangskode 0
GO TO FULL VERSION