CodeGym /Java Blog /Random-IT /Metodo Wait() in Java
John Squirrels
Livello 41
San Francisco

Metodo Wait() in Java

Pubblicato nel gruppo Random-IT
In questo articolo, esamineremo il metodo wait() per controllare il thread e i metodi notify() / notifyAll() . Questi metodi sono definiti nella classe base java.lang.Object e, di conseguenza, i meccanismi di ereditarietà presenti in Java forniscono questi metodi a tutte le classi. Cioè, quando crei la tua classe e i suoi oggetti, puoi sempre chiamare questi metodi.

Come funzionano i metodi wait() e notify()/notifyAll()?

  • aspetta() . in breve, questo metodo rilascia il monitor e mette il thread chiamante in uno stato di attesa fino a quando un altro thread chiama il metodo notify() / notifyAll() ;
  • notifica() . Continua il lavoro di un thread il cui metodo wait() è stato precedentemente chiamato;
  • Il metodo notifyAll() riprende tutti i thread a cui è stato precedentemente chiamato il metodo wait() .
Ora diamo un'occhiata più da vicino al metodo wait() . La classe Object contiene tre opzioni per questo metodo:
  • public final native void wait(long timeoutMillis) getta InterruptedException ; Fa sì che il thread corrente attenda finché non viene risvegliato. Solitamente avviene per notifica o interruzione, oppure fino a quando non è trascorso un certo periodo di tempo reale.

  • public final void wait() genera InterruptedException . Non a caso abbiamo scritto un metodo senza parametri come il secondo. Infatti, se guardi il suo codice, si riferisce alla prima variante del metodo, ha solo l'argomento 0L.

  • public final wait​(long timeout, int nanos) . Fa in modo che il thread corrente attenda fino a quando non viene risvegliato, in genere tramite notifica o interruzione o fino a quando non è trascorso un certo periodo di tempo reale.

Il metodo wait() ha lo scopo di sospendere il thread chiamante. Cosa significa? Questi metodi appartengono alla classe. In base alla classe, crei un oggetto. Gli oggetti esistono in alcuni thread. Cioè, gli oggetti vengono creati in alcuni thread. Nel thread in cui funziona questo oggetto, se chiami wait() in esso, questo porterà al fatto che questo thread si fermerà. L'oggetto stesso agisce come una sorta di monitor. Che cos'è? È chiaro che puoi creare diversi oggetti e tutti conterranno il wait()metodo. C'è una comprensione di quale oggetto ha causato l'arresto di un particolare thread. Il thread si ferma e attende finché è scritto nel parametro. E poi inizierà. Questo thread non può avviarsi da solo. Per riprendere il lavoro, ci sono i metodi notify e notifyAll. Una chiamata a notify() o notifyAll() deve riprodurre qualche altro thread. Con wait() , puoi interrompere più thread e avviare tutti i thread con notifyAll() . Se più thread sono stati arrestati ed è stato chiamato notify() , è impossibile dire esattamente quale thread riprenderà questo metodo. Se non ci sono thread in attesa sul metodo wait() , allora non accade nulla quando notify() oviene chiamato notifyAll() . Un thread può chiamare i metodi wait() o notify() su un particolare oggetto solo se attualmente dispone di un blocco su quell'oggetto. wait() , notify() e notifyAll() dovrebbero essere chiamati solo dal codice sincronizzato.

Esempio di metodo Wait()

Qui abbiamo uno degli esempi più popolari che illustra come funziona il metodo. Diciamo che abbiamo un negozio, un produttore e un consumatore. Il produttore trasferisce alcuni prodotti di produzione al negozio, dopodiché il consumatore può prenderli. Lascia che il produttore debba produrre rispettivamente 8 beni, il consumatore deve acquistarli tutti. Ma allo stesso tempo, non possono essere presenti più di 6 articoli contemporaneamente nel magazzino. Per risolvere questo problema, utilizziamo i metodi wait() e notify() . Definiamo tre classi: Market , Manufacturer e Client . Il metodo Manufacturer nel metodo run() aggiunge 8 prodotti all'oggetto Market usando il suometodo put() . Il client nel metodo run() in un ciclo chiama il metodo get dell'oggetto Market per ottenere questi prodotti. I metodi put e get della classe Market sono sincronizzati. Per tracciare la presenza di merci nella classe Market , controlliamo il valore della variabile item. Il metodo get() per ottenere un prodotto dovrebbe attivarsi solo se esiste almeno un prodotto. Pertanto, nel metodo get, controlliamo se manca il prodotto. Se l'elemento non è disponibile, viene chiamato il metodo wait() . Questo metodo rilascia il monitor dell'oggetto Market e blocca il metodo get fino a quando notify()metodo viene chiamato sullo stesso monitor. Quando un elemento viene aggiunto nel metodo put() e viene chiamato notify() , il metodo get() ottiene il monitor. Successivamente, il nostro cliente riceve un articolo. A tale scopo, viene visualizzato un messaggio e il valore dell'elemento viene decrementato. Infine, la chiamata al metodo notify() segnala al metodo put() di continuare. Nel metodo put() , una logica simile funziona, solo ora il metodo put() dovrebbe funzionare se non ci sono più di 6 prodotti nel Market .

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();
   }
}
Qui, usando wait() nel metodo get() , stiamo aspettando che il produttore aggiunga un nuovo articolo. E dopo aver aggiunto, chiamiamo notify() , come per dire che un posto è diventato libero su Warehouse e puoi aggiungerne altri. Nel metodo put() , utilizzando wait() , stiamo aspettando il rilascio di spazio su Warehouse . Dopo che lo spazio è libero, aggiungiamo l'oggetto, notify() avvia il thread e il Cliente può ritirare l'oggetto. Ecco l'output del nostro programma:
Il produttore ha aggiunto 1 articolo in più... Ora ci sono 1 articoli in magazzino Il produttore ha aggiunto 1 articolo in più... Ora ci sono 2 articoli in magazzino Il produttore ha aggiunto 1 articolo in più... Ora ci sono 3 articoli in magazzino Il produttore ha aggiunto 1 altro articolo... Ora ci sono 4 articoli nel magazzino Il produttore ha aggiunto 1 altro articolo... Ora ci sono 5 articoli nel magazzino Il produttore ha aggiunto 1 altro articolo... Ora ci sono 6 articoli nel magazzino Un cliente ha acquistato 1 articolo... Quantità articoli nel magazzino Market... 5 Un cliente ha acquistato 1 articolo... Quantità articoli nel magazzino Market... 4 Un cliente ha acquistato 1 articolo... Quantità articoli nel magazzino Market... 3 Un cliente ha acquistato 1 articolo... Quantità articoli nel magazzino Market... 2 Un cliente ha acquistato 1 articolo... Quantità articoli nel magazzino Market... 1 Un cliente ha acquistato 1 articolo... Quantità articoli nel magazzino Market ...0 Il produttore ha aggiunto 1 articolo in più... Ora ci sono 1 articoli nel magazzino Il produttore ha aggiunto 1 articolo in più... Ora ci sono 2 articoli nel magazzino Un cliente ha acquistato 1 articolo... Quantità di articoli nel magazzino del mercato... 1 Un cliente ha acquistato 1 articolo... Quantità di articoli nel magazzino del mercato... 0 Processo terminato con codice di uscita 0
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION