Differenza tra attesa e sonno in Java

1. Panoramica

In questo breve articolo, daremo un'occhiata ai metodi standard sleep () e wait () nel core Java e capiremo le differenze e le somiglianze tra di loro.

2. Differenze generali tra attesa e sonno

In poche parole, wait () è un metodo di istanza utilizzato per la sincronizzazione dei thread.

Può essere chiamato su qualsiasi oggetto, poiché è definito direttamente su java.lang.Object, ma può essere chiamato solo da un blocco sincronizzato . Rilascia il blocco sull'oggetto in modo che un altro thread possa saltare e acquisire un blocco.

D'altra parte, Thread.sleep () è un metodo statico che può essere chiamato da qualsiasi contesto. Thread.sleep () sospende il thread corrente e non rilascia alcun blocco.

Ecco uno sguardo iniziale molto semplicistico a queste due API principali in azione:

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"); } } 

L'esecuzione di questo esempio produrrà il seguente output:

Il thread "principale" viene riattivato dopo 1 secondo di sonno

L'oggetto "[email protected]" viene riattivato dopo aver atteso 1 secondo

3. Svegliarsi Aspetta e dormi

Quando usiamo il metodo sleep () , un thread viene avviato dopo un intervallo di tempo specificato, a meno che non venga interrotto.

Per wait () , il processo di risveglio è un po 'più complicato. Possiamo riattivare il thread chiamando i metodi notify () o notifyAll () sul monitor su cui si attende.

Usa notifyAll () invece di notify () quando vuoi riattivare tutti i thread che si trovano nello stato di attesa. Analogamente al metodo wait () stesso, notify () e notifyAll () devono essere chiamati dal contesto sincronizzato.

Ad esempio, ecco come puoi aspettare :

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); }

E poi, ecco come un altro thread può quindi riattivare il thread in attesa, chiamando notify () sul monitor :

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

L'esecuzione di questo esempio produrrà il seguente output:

In attesa del completamento di ThreadB ...

ThreadB è stato completato. La somma di quel thread è: 704982704

4. Conclusione

Questo un breve primer per la semantica di attesa e di sonno in Java.

In generale, dovremmo usare sleep () per controllare il tempo di esecuzione di un thread e wait () per la sincronizzazione multi-thread. Naturalmente, c'è molto di più da esplorare, dopo aver compreso bene le basi.

Come sempre, puoi controllare gli esempi forniti in questo articolo su GitHub.