Diferența dintre așteptați și dormiți în Java

1. Prezentare generală

În acest scurt articol, vom arunca o privire asupra metodelor standard sleep () și wait () din Java de bază și vom înțelege diferențele și asemănările dintre ele.

2. Diferențe generale între așteptare și somn

Pur și simplu, wait () este o metodă de instanță utilizată pentru sincronizarea firelor.

Poate fi apelat pe orice obiect, așa cum este definit chiar pe java.lang.Object, dar poate fi apelat doar dintr-un bloc sincronizat . Eliberează încuietoarea obiectului, astfel încât un alt fir să poată sări și să obțină o încuietoare.

Pe de altă parte, Thread.sleep () este o metodă statică care poate fi apelată din orice context. Thread.sleep () întrerupe firul curent și nu eliberează nicio blocare.

Iată o privire inițială foarte simplistă asupra acestor două API-uri principale în acțiune:

private static Object LOCK = new Object(); private static void sleepWaitExamples() throws InterruptedException { Thread.sleep(1000); System.out.println( "Thread '" + Thread.currentThread().getName() + "' is woken after sleeping for 1 second"); synchronized (LOCK) { LOCK.wait(1000); System.out.println("Object '" + LOCK + "' is woken after" + " waiting for 1 second"); } } 

Rularea acestui exemplu va produce următoarea ieșire:

Firul „principal” este trezit după ce ați dormit 1 secundă

Obiectul „[email protected]” este trezit după ce așteptați 1 secundă

3. Trezirea Așteptați și dormiți

Când folosim metoda sleep () , un fir începe după un interval de timp specificat, cu excepția cazului în care este întrerupt.

For wait () , procesul de trezire este puțin mai complicat. Putem trezi firul apelând fie metodele de notificare (), fie notificareAll () de pe monitorul pe care se așteaptă.

Utilizați notificationAll () în loc de notification () când doriți să activați toate firele care se află în starea de așteptare. În mod similar cu metoda wait () în sine, notification () și notificationAll () trebuie apelate din contextul sincronizat.

De exemplu, iată cum puteți aștepta :

synchronized (b) { while (b.sum == 0) { System.out.println("Waiting for ThreadB to complete..."); b.wait(); } System.out.println("ThreadB has completed. " + "Sum from that thread is: " + b.sum); }

Și apoi, iată cum un alt fir poate trezi apoi firul de așteptare - apelând notification () pe monitor :

int sum; @Override public void run() { synchronized (this) { int i = 0; while (i < 100000) { sum += i; i++; } notify(); } }

Rularea acestui exemplu va produce următoarea ieșire:

Se așteaptă finalizarea ThreadB ...

ThreadB s-a finalizat. Suma din acel fir este: 704982704

4. Concluzie

Acesta este un manual rapid pentru semantica așteptării și somnului în Java.

În general, ar trebui să folosim sleep () pentru controlul timpului de execuție al unui thread și wait () pentru sincronizarea multi-thread. Bineînțeles, mai sunt multe de explorat - după ce înțelegem bine elementele de bază.

Ca întotdeauna, puteți consulta exemplele furnizate în acest articol pe GitHub.