Differenza tra wait () e sleep ()
-
10-07-2019 - |
Domanda
Qual è la differenza tra wait ()
e sleep ()
nelle discussioni?
Comprendo che un thread wait ()
è ancora in modalità di esecuzione e utilizza cicli CPU ma un sleep ()
non consuma alcun ciclo CPU corretta?
Perché abbiamo entrambi wait ()
e sleep ()
: come varia la loro implementazione a un livello inferiore?
Soluzione
A wait
può essere " svegliato " da un altro thread che chiama notifica
sul monitor che è in attesa mentre un sleep
impossibile. Inoltre, wait
(e notifica
) deve avvenire in un blocco sincronizzato
sull'oggetto monitor mentre sleep
non:
Object mon = ...;
synchronized (mon) {
mon.wait();
}
A questo punto il thread attualmente in esecuzione attende e rilascia il monitor . Un'altra discussione potrebbe fare
synchronized (mon) { mon.notify(); }
(sullo stesso oggetto mon
) e il primo thread (supponendo che sia l'unico thread in attesa sul monitor) si riattiverà.
Puoi anche chiamare notifyAll
se più di un thread è in attesa sul monitor & # 8211; questo risveglierà tutti . Tuttavia, solo uno dei thread sarà in grado di afferrare il monitor (ricorda che wait
si trova in un blocco sincronizzato
) e continua & # 8211; gli altri verranno quindi bloccati fino a quando non saranno in grado di acquisire il blocco del monitor.
Un altro punto è che si chiama wait
su Object
stesso (vale a dire che aspetti sul monitor di un oggetto) mentre chiami sleep
su Discussione
.
Ancora un altro punto è che puoi ottenere risvegli spuri da wait
(cioè il thread in attesa riprende senza una ragione apparente). Devi sempre attendere
mentre giri su una condizione come segue:
synchronized {
while (!condition) { mon.wait(); }
}
Altri suggerimenti
Una differenza chiave non ancora menzionata è che durante la sospensione di un thread non rilascia i blocchi che contiene, mentre in attesa rilascia il blocco sull'oggetto che wait ()
è chiamato.
synchronized(LOCK) {
Thread.sleep(1000); // LOCK is held
}
synchronized(LOCK) {
LOCK.wait(); // LOCK is not held
}
Ho trovato questo post utile. Mette la differenza tra Thread.sleep ()
, Thread.yield ()
e Object.wait ()
in termini umani. Per citare:
Alla fine tutto si dirige verso lo scheduler del sistema operativo, che distribuisce timeslices a processi e thread.
sleep (n)
dice & # 8220; Ho finito con il mio timeslice, e per favore don & # 8217; t dammi un altro per almeno n millisecondi. & # 8221; Il sistema operativo non prova nemmeno a programmare il thread dormiente fino a quando non è trascorso il tempo richiesto.
yield ()
dice & # 8220; Ho finito con il mio timeslice, ma ho ancora del lavoro da fare fare. & # 8221; Il sistema operativo è libero di assegnare immediatamente alla discussione un'altra sequenza temporale, o per dare qualche altro thread o elaborare la CPU il thread cedente ho appena rinunciato.
wait ()
dice & # 8220; Ho finito con il mio timeslice. Non darmene un altro timeslice fino a quando qualcuno chiama avvisa (). & # 8221; Come consleep ()
, il sistema operativo ha vinto & # 8217; t prova anche a pianificare la tua attività a meno che qualcuno non chiaminotification ()
(o uno di si verificano alcuni altri scenari di attivazione).I thread perdono anche il resto del loro timeslice quando si esibiscono bloccare l'IO e in poche altre circostanze. Se una discussione funziona durante l'intero periodo di tempo, il sistema operativo assume il controllo forzatamente all'incirca se era stato chiamato
yield ()
, in modo che altri processi possano essere eseguiti.Raramente hai bisogno di
yield ()
, ma se disponi di un'app pesante limiti logici delle attività, l'inserimento di unyield ()
potrebbe migliorare il sistema reattività (a scapito del tempo & # 8212; cambi di contesto, anche solo al sistema operativo e viceversa, non sono gratuiti). Misura e testa contro i tuoi obiettivi preoccupati, come sempre.
Ci sono molte risposte qui ma non sono riuscito a trovare la distinzione semantica menzionata su nessuna.
Non si tratta del thread stesso; entrambi i metodi sono richiesti in quanto supportano casi d'uso molto diversi.
sleep ()
invia il thread alla modalità sospensione come era prima, impacchetta semplicemente il contesto e interrompe l'esecuzione per un tempo predefinito. Quindi, per svegliarlo prima del dovuto, è necessario conoscere il riferimento al thread. Questa non è una situazione comune in un ambiente multi-thread. Viene utilizzato principalmente per la sincronizzazione temporale (ad es. Sveglia in esattamente 3,5 secondi) e / o equità codificata (basta dormire un po 'e lasciare che gli altri thread funzionino).
wait ()
, al contrario, è un meccanismo di sincronizzazione di thread (o messaggi) che consente di notificare un thread di cui non si ha alcun riferimento memorizzato (né cura). Puoi considerarlo come un modello di pubblicazione-iscrizione ( wait
== iscriviti e notifica ()
== pubblica). Fondamentalmente usando Notify () stai inviando un messaggio (che potrebbe anche non essere ricevuto affatto e normalmente non ti interessa).
Per riassumere, normalmente si utilizza sleep ()
per la sincronizzazione del tempo e wait ()
per la sincronizzazione multi-thread.
Potrebbero essere implementati nello stesso modo nel sistema operativo sottostante, o per niente (dato che le versioni precedenti di Java non avevano un vero multithreading; probabilmente anche alcune piccole VM non lo fanno). Non dimenticare che Java gira su una VM, quindi il tuo codice verrà trasformato in qualcosa di diverso a seconda della VM / OS / HW su cui gira.
Qui ho elencato alcune importanti differenze tra i metodi wait ()
e sleep ()
.
PS: Fai anche clic sui link per vedere il codice della libreria (funzionamento interno, basta giocare un po 'per una migliore comprensione).
wait ()
-
Il metodo
-
wait ()
rilascia il blocco. -
wait ()
è il metodo della classeObject
. -
wait ()
è il metodo non statico -void wait pubblico () genera InterruptedException {// ...}
-
wait ()
deve essere notificato con i metodinotification ()
onotificationAll ()
.
Il metodo wait ()
deve essere chiamato da un loop per gestire i falsi allarmi.
Il metodo wait ()
deve essere chiamato dal contesto sincronizzato (cioè metodo o blocco sincronizzato), altrimenti genereràIllegalMonitorStateException
sleep ()
-
Il metodo
-
sleep ()
non rilascia il blocco. -
sleep ()
è il metodo della classejava.lang.Thread
. -
sleep ()
è il metodo statico -sleep vuoto statico pubblico (long millis, int nanos) genera InterruptedException {// ...}
- dopo il periodo di tempo specificato,
sleep ()
è completato. -
sleep ()
è meglio non chiamare dal loop (ovvero vedi il codice qui sotto ). -
sleep ()
può essere chiamato da qualsiasi luogo. non esiste un requisito specifico.
Rif: Differenza tra Wait e Sleep
Snippet di codice per la chiamata del metodo wait and sleep
synchronized(monitor){
while(condition == true){
monitor.wait() //releases monitor lock
}
Thread.sleep(100); //puts current thread on Sleep
}
Ci sono alcune note chiave sulla differenza che concludo dopo aver lavorato su wait e sleep, per prima cosa dai un'occhiata all'esempio usando wait () e sleep ():
Esempio1 : utilizzando attendi () e sospensione ():
synchronized(HandObject) {
while(isHandFree() == false) {
/* Hand is still busy on happy coding or something else, please wait */
HandObject.wait();
}
}
/* Get lock ^^, It is my turn, take a cup beer now */
while (beerIsAvailable() == false) {
/* Beer is still coming, not available, Hand still hold glass to get beer,
don't release hand to perform other task */
Thread.sleep(5000);
}
/* Enjoy my beer now ^^ */
drinkBeers();
/* I have drink enough, now hand can continue with other task: continue coding */
setHandFreeState(true);
synchronized(HandObject) {
HandObject.notifyAll();
}
Chiarisci alcune note chiave:
- Chiama :
- wait (): chiama il thread corrente che contiene HandObject Object
- sleep (): Call on Thread esegue task get beer (è il metodo class quindi influenza sul thread corrente)
- sincronizzato :
- wait (): quando l'accesso multi-thread sincronizzato accede allo stesso oggetto (HandObject) (quando è necessaria la comunicazione tra più thread (thread esegui codifica, thread esegui ottieni birra) accedi allo stesso oggetto HandObject)
- sleep (): durante l'attesa per continuare l'esecuzione (Waiting beer available)
- Blocca blocco :
- wait (): rilascia il blocco per altri oggetti che hanno la possibilità di eseguire (HandObject è gratuito, puoi fare un altro lavoro)
- sleep (): mantieni il blocco per almeno t volte (o fino all'interruzione) (Il mio lavoro non è ancora terminato, continuo a bloccare il blocco e aspetto che continuino alcune condizioni)
- Condizioni di sveglia :
- wait (): fino alla chiamata notification (), notifyAll () dall'oggetto
- sleep (): fino almeno alla scadenza o alla chiamata di interruzione
- E l'ultimo punto è usa quando come estani indica:
normalmente usi sleep () per la sincronizzazione temporale e wait () per multi-thread-sincronizzazione.
Per favore, correggimi se sbaglio.
Differenza tra wait () e sleep ()
-
La differenza fondamentale è che
wait ()
proviene daObject
esleep ()
è un metodo statico diDiscussione
. -
La differenza principale è che
wait ()
rilascia il blocco mentresleep ()
non rilascia alcun blocco durante l'attesa. wait ()
viene utilizzato per la comunicazione tra thread mentresleep ()
viene utilizzato per introdurre una pausa nell'esecuzione, in generale.wait ()
dovrebbe essere chiamato dall'interno sincronizzato oppure otteniamo unIllegalMonitorStateException
, mentresleep ()
può essere chiamato ovunque.- Per ricominciare una discussione da
wait ()
, devi chiamarenotify ()
onotificationAll ()
. Per quanto riguardasleep (),
il thread inizia dopo un intervallo di tempo specificato.
Analogie
- Entrambi fanno passare il thread corrente allo stato Non eseguibile .
- Entrambi sono metodi nativi .
Questa è una domanda molto semplice, perché entrambi questi metodi hanno un uso totalmente diverso.
La differenza principale è aspettare di rilasciare il blocco o il monitor mentre il sonno non rilascia alcun blocco o monitor durante l'attesa. Wait viene utilizzato per la comunicazione tra thread mentre sleep viene utilizzato per introdurre una pausa nell'esecuzione.
Questa era solo una spiegazione chiara e di base, se vuoi di più, continua a leggere.
In caso di wait ()
il thread va nello stato di attesa e non ritorna automaticamente finché non chiamiamo il metodo notification ()
(o notifyAll ()
se hai più di un thread in stato di attesa e vuoi riattivare tutti quei thread). E hai bisogno di sincronizzazione o blocco oggetto o blocco classe per accedere ai metodi wait ()
o notification ()
o notifyAll ()
. E un'altra cosa, il metodo wait ()
viene utilizzato per la comunicazione tra thread perché se un thread va in stato di attesa avrai bisogno di un altro thread per riattivare quel thread.
Ma in caso di sleep ()
questo è un metodo che viene utilizzato per conservare il processo per alcuni secondi o il tempo desiderato. Perché non è necessario provocare alcun metodo notification ()
o notifyAll ()
per riavere quel thread. Oppure non hai bisogno di nessun altro thread per richiamare quel thread. Ad esempio, se vuoi che qualcosa accada dopo alcuni secondi, come in un gioco dopo il turno dell'utente, vuoi che l'utente attenda fino alla riproduzione del computer, quindi puoi menzionare il metodo sleep ()
.
E un'altra importante differenza che viene chiesta spesso nelle interviste: sleep ()
appartiene alla classe Thread
e wait ()
appartiene a < code> Object class.
Queste sono tutte le differenze tra sleep ()
e wait ()
.
E c'è una somiglianza tra i due metodi: entrambi sono istruzioni verificate, quindi è necessario provare a catturare o lanciare per accedere a questi metodi.
Spero che questo ti possa aiutare.
fonte: http://www.jguru.com/faq/view. jsp? EID = 47127
Discussione .sleep ()
invia il thread corrente nello stato " Non eseguibile " per un certo periodo di tempo. Il thread mantiene i monitor acquisiti - cioè se il thread è attualmente in un blocco o metodo sincronizzato, nessun altro thread può entrare in questo blocco o metodo. Se un altro thread chiamat.interrupt ()
risveglierà il thread dormiente.Nota che il sonno è un metodo statico, il che significa che influenza sempre il thread corrente (quello che sta eseguendo il metodo sleep). UN errore comune è chiamare
t.sleep ()
dove t è un thread diverso; anche allora, sarà il thread corrente a dormire, non il thread t.
t .suspend ()
è obsoleto. Usandolo è possibile arrestare un thread diverso rispetto al thread corrente. Un thread sospeso mantiene tutti i suoi monitor e poiché questo stato non è interrompibile, è soggetto a deadlock.
object .wait ()
invia il thread corrente nello stato " Non eseguibile " , comesleep ()
, ma con una svolta. L'attesa viene chiamata su un oggetto, non a filo; chiamiamo questo oggetto l'oggetto "lock". " Prima dilock.wait ()
chiamato, il thread corrente deve sincronizzarsi sull'oggetto lock;wait ()
quindi rilascia questo blocco e aggiunge il thread alla " lista di attesa " associato alla serratura. Successivamente, un altro thread può sincronizzarsi sul stesso oggetto di blocco e chiamalock.notify ()
. Questo sveglia l'originale, filo in attesa. Fondamentalmente,wait ()
/notification ()
è comesleep ()
/interrupt ()
, solo il thread attivo non ha bisogno di un direct puntatore al thread dormiente, ma solo all'oggetto lock condiviso.
Aspettare e dormire sono due cose diverse:
- In
sleep ()
il thread smette di funzionare per la durata specificata. - In
wait ()
il thread smette di funzionare fino a quando l'oggetto in attesa non viene notificato, generalmente da altri thread.
sleep
è un metodo di Thread
, wait
è un metodo di Object
, quindi wait / notification
è una tecnica di sincronizzazione dei dati condivisi in Java (utilizzando monitor ), ma sleep
è un semplice metodo di thread per mettere in pausa se stesso.
sleep () è un metodo che viene utilizzato per trattenere il processo per alcuni secondi o il tempo desiderato, ma in caso di attesa () il thread del metodo passa in stato di attesa e non verrà indietro automaticamente fino a quando non chiamiamo notify () o notifyAll ().
La differenza sostanziale è che wait () rilascia il blocco o il monitor mentre sleep () non rilascia alcun blocco o monitor durante l'attesa. Wait viene utilizzato per la comunicazione tra thread mentre sleep viene utilizzato per introdurre una pausa nell'esecuzione, in generale.
Thread.sleep () invia il thread corrente allo stato "Non eseguibile" per un certo periodo di tempo. Il thread mantiene i monitor che ha acquisito, ovvero se il thread è attualmente in un blocco o metodo sincronizzato, nessun altro thread può accedere a questo blocco o metodo. Se un altro thread chiama t.interrupt (), il thread inattivo verrà attivato. Si noti che sleep è un metodo statico, il che significa che influenza sempre il thread corrente (quello che sta eseguendo il metodo sleep). Un errore comune è chiamare t.sleep () dove t è un thread diverso; anche allora, sarà il thread corrente a dormire, non il thread t.
object.wait () invia il thread corrente allo stato "Non eseguibile", come sleep (), ma con una svolta. L'attesa viene chiamata su un oggetto, non su un thread; chiamiamo questo oggetto "oggetto lock". Prima di chiamare lock.wait (), il thread corrente deve sincronizzarsi sull'oggetto lock; wait () quindi rilascia questo blocco e aggiunge il thread alla "lista di attesa" associata al blocco. Successivamente, un altro thread può sincronizzarsi sullo stesso oggetto lock e chiamare lock.notify (). Questo riattiva il thread di attesa originale. In sostanza, wait () / notification () è come sleep () / interrupt (), solo il thread attivo non ha bisogno di un puntatore diretto al thread inattivo, ma solo all'oggetto lock condiviso.
synchronized(LOCK) {
Thread.sleep(1000); // LOCK is held
}
synchronized(LOCK) {
LOCK.wait(); // LOCK is not held
}
Lascia che categorizzi tutti i punti sopra:
Chiama:
- wait (): chiama un oggetto; il thread corrente deve sincronizzarsi sull'oggetto lock.
- sleep (): chiama su una discussione; eseguendo sempre thread.
Sincronizzato:
- wait (): quando più thread sincronizzati accedono allo stesso oggetto uno per uno.
- sleep (): quando i thread multipli sincronizzati attendono lo sleep oltre il thread inattivo.
Blocco blocco:
- wait (): rilascia il blocco per consentire ad altri oggetti di eseguire.
- sleep (): mantieni il blocco per almeno t volte se il timeout specificato o qualcuno interrompe.
Condizioni di sveglia:
- wait (): fino alla notifica di chiamata (), notifyAll () dall'oggetto
- sleep (): fino almeno alla scadenza o alla chiamata di interruzione ().
Usage:
- sleep (): per la sincronizzazione oraria e;
- wait (): per la sincronizzazione multi-thread.
Rif: diff sleep
e wait
?? wait
e sleep
sono molto diversi:
-
sleep
non ha modo di " svegliarsi " ;, - considerando che
wait ha un modo di "svegliarsi" durante il periodo di attesa, con un altro thread che chiamanotifica
oNotifyAll
.
Vieni a pensarci, i nomi sono confusi in questo senso; tuttavia sleep
è un nome standard e wait
è come WaitForSingleObject
o WaitForMultipleObjects
nell'API Win.
In parole semplici, wait is wait Fino a quando qualche altro thread non ti invoca mentre sleep è "non eseguire la prossima istruzione" per un determinato periodo di tempo.
Inoltre sleep è un metodo statico nella classe Thread e funziona su thread, mentre wait () è nella classe Object e chiamato su un oggetto.
Un altro punto, quando si chiama wait su un oggetto, il thread coinvolto sincronizza l'oggetto e quindi attende. :)
Da questo post: http://javaconceptoftheday.com / differenza-tra-attendista sonno-metodi-in-java-/
Metodowait ().
1) Il thread che chiama il metodo wait () rilascia il blocco che contiene.
2) Il thread riacquista il blocco dopo che altri thread chiamano i metodi notify () o notifyAll () sullo stesso blocco.
3) Il metodo wait () deve essere chiamato all'interno del blocco sincronizzato.
4) Il metodo wait () viene sempre chiamato sugli oggetti.
5) I thread in attesa possono essere attivati ??da altri thread chiamando i metodi notify () o notifyAll ().
6) Per chiamare il metodo wait (), il thread deve avere il blocco degli oggetti.
Metodo sleep ()
1) Il thread che chiama il metodo sleep () non rilascia il blocco che contiene.
2) Il metodo sleep () può essere chiamato all'interno o all'esterno del blocco sincronizzato.
3) Il metodo sleep () viene sempre chiamato sui thread.
4) I thread dormienti non possono essere svegliati da altri thread. Altrimenti, il thread genererà InterruptedException.
5) Per chiamare il metodo sleep (), il thread non deve avere il blocco degli oggetti.
wait ()
è un metodo della classeObject
.
sleep ()
è un metodo della classeThread
.sleep ()
consente al thread di passare allo statosleep
per x millisecondi.
Quando un thread passa allo stato di sospensionenon rilascia il blocco
.wait ()
consente al thread di rilasciare il blocco epassa allo stato sospeso
.
Questo thread sarà attivo quando un metodonotification ()
onotifAll ()
è chiamato per lo stesso oggetto.
Una potenziale grande differenza tra sospensione / interruzione e attesa / notifica è quella
- chiamando
interrupt ()
durantesleep ()
genera sempre un'eccezione (ad es. InterruptedException ), mentre - chiamando
avvisare ()
durantewait ()
no.
Generare un'eccezione quando non necessario è inefficiente. Se hai thread che comunicano tra loro ad alta velocità, genererebbe molte eccezioni se chiamassi interrupt per tutto il tempo, il che è uno spreco totale di CPU.
Hai ragione - Sleep () fa sì che quel thread su "sleep" e la CPU si spegne ed elabora altri thread (altrimenti noti come commutazione di contesto) dove credo che Wait continui a elaborare la thread corrente della CPU.
Abbiamo entrambi perché, anche se può sembrare ragionevole lasciare che altre persone utilizzino la CPU mentre non la si utilizza, in realtà c'è un overhead al cambio di contesto - a seconda di quanto dura il sonno, può essere più costoso nei cicli della CPU per cambiare thread di quanto non sia semplicemente fare in modo che il thread non faccia nulla per alcuni ms.
Nota anche che il sonno forza un cambio di contesto.
Inoltre - in generale non è possibile controllare il cambio di contesto - durante l'attesa il sistema operativo può (e farà attendere più a lungo) la scelta di elaborare altri thread.
I metodi sono usati per cose diverse.
Thread.sleep(5000); // Wait until the time has passed.
Object.wait(); // Wait until some other thread tells me to wake up.
Thread.sleep (n) può essere interrotto, ma Object.wait () deve essere avvisato.
È possibile specificare il tempo massimo di attesa: Object.wait (5000)
in modo da poter utilizzare wait
su, er, sleep
ma poi devi preoccuparti delle serrature.
Nessuno dei due metodi utilizza la CPU durante il sonno / attesa.
I metodi sono implementati usando codice nativo, usando costrutti simili ma non allo stesso modo.
Cerca te stesso: È disponibile il codice sorgente dei metodi nativi? Il file /src/share/vm/prims/jvm.cpp
è il punto di partenza ...
Qui wait () sarà nello stato di attesa fino a quando non verrà notificato da un altro thread, ma dove sleep () avrà qualche tempo..dopo che passerà automaticamente allo stato Pronto ...
Aspettare () e dormire () Differenze?
Thread.sleep () Una volta completato il suo lavoro, rilascia solo il blocco a tutti. fino a quando non rilascia mai il blocco a nessuno.
Sleep() take the key, its never release the key to anyone, when its work completed then only its release then only take the key waiting stage threads.
Object.wait () Quando sta per attendere, verrà rilasciato il tasto e attenderà alcuni secondi in base al parametro.
Ad esempio:
prendi il caffè nella tua mano destra, puoi prenderne un altro della stessa mano, quando lo poserai, prenderai solo un altro oggetto dello stesso tipo qui. anche. questo è sleep () stai dormendo non hai lavorato, stai dormendo solo .. lo stesso anche qui.
wait (). quando sei messo giù e prendi un altro mezzo mentre aspetti, quello è aspettare
stai riproducendo un film o qualsiasi altra cosa nel tuo sistema come un giocatore che non puoi riprodurre più di uno alla volta, ecco qui, quando chiudi e scegli un altro film o canzone che significa mentre è chiamato wait
wait
rilascia il blocco e sleep
no. Un thread in stato di attesa è idoneo al risveglio non appena viene chiamato notification
o notificationAll
. Ma in caso di sleep
il thread mantiene il blocco e sarà idoneo solo al termine del tempo di sleep.
sleep ()
fa sì che il thread corrente passi dallo stato in esecuzione allo stato di blocco per un tempo specificato. Se il thread corrente ha il blocco di qualsiasi oggetto, continua a trattenerlo, il che significa che altri thread non possono eseguire alcun metodo sincronizzato nell'oggetto classe.
wait ()
fa sì che il thread corrente vada nello stato di blocco per un tempo specificato o fino a quando non viene notificato, ma in questo caso il thread rilascia il blocco dell'oggetto (il che significa che altri thread può eseguire qualsiasi metodo sincronizzato dell'oggetto chiamante.
A mio avviso, la differenza principale tra entrambi i meccanismi è che sleep / interrupt è il modo più semplice di gestire i thread, mentre wait / notification è un'astrazione volta a semplificare l'intercettazione dei thread. Ciò significa che sleep / interrupt può fare qualsiasi cosa, ma che questo compito specifico è più difficile da svolgere.
Perché aspettare / notifica è più adatto? Ecco alcune considerazioni personali:
Impone la centralizzazione. Permette di coordinare la comunicazione tra un gruppo di thread con un singolo oggetto condiviso. Questo semplifica molto il lavoro.
Applica la sincronizzazione. Perché fa sì che il programmatore avvolga la chiamata in attesa / notifica in un blocco sincronizzato.
È indipendente dall'origine e dal numero di thread. Con questo approccio puoi aggiungere arbitrariamente più thread senza modificare gli altri thread o tenere traccia di quelli esistenti. Se hai usato sleep / interrupt, per prima cosa dovresti conservare i riferimenti ai thread dormienti, quindi interromperli uno a uno, a mano.
Un esempio della vita reale che è buono per spiegare questo è un ristorante classico e il metodo che il personale usa per comunicare tra loro: i camerieri lasciano le richieste dei clienti in un posto centrale (una bacheca di sughero, un tavolo, ecc. .), suona un campanello e gli operai della cucina vengono a prendere tali richieste. Una volta che c'è un corso pronto, il personale della cucina suona nuovamente il campanello in modo che i camerieri siano consapevoli e li portino ai clienti.
L'esempio su sleep non rilascia il blocco e aspetta
Qui ci sono due classi:
- Principale : contiene il metodo principale e due thread.
Singleton : questa è la classe singleton con due metodi statici getInstance () e getInstance (booleano isWait).
public class Main { private static Singleton singletonA = null; private static Singleton singletonB = null; public static void main(String[] args) throws InterruptedException { Thread threadA = new Thread() { @Override public void run() { singletonA = Singleton.getInstance(true); } }; Thread threadB = new Thread() { @Override public void run() { singletonB = Singleton.getInstance(); while (singletonA == null) { System.out.println("SingletonA still null"); } if (singletonA == singletonB) { System.out.println("Both singleton are same"); } else { System.out.println("Both singleton are not same"); } } }; threadA.start(); threadB.start(); } }
e
public class Singleton {
private static Singleton _instance;
public static Singleton getInstance() {
if (_instance == null) {
synchronized (Singleton.class) {
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
public static Singleton getInstance(boolean isWait) {
if (_instance == null) {
synchronized (Singleton.class) {
if (_instance == null) {
if (isWait) {
try {
// Singleton.class.wait(500);//Using wait
Thread.sleep(500);// Using Sleep
System.out.println("_instance :"
+ String.valueOf(_instance));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
_instance = new Singleton();
}
}
}
return _instance;
}
}
Ora esegui questo esempio otterrai un output inferiore:
_instance :null
Both singleton are same
Qui le istanze Singleton create da threadA e threadB sono uguali. Significa che il thread B è in attesa all'esterno fino al rilascio del thread A è bloccato.
Ora cambia Singleton.java commentando Thread.sleep (500); metodo e decommentando Singleton.class.wait (500); . Qui a causa di Singleton.class.wait (500); il metodo threadA rilascerà tutti i blocchi acquisiti e si sposta nello stato "Non eseguibile", il thread B riceverà le modifiche per entrare nel blocco sincronizzato.
Ora esegui di nuovo:
SingletonA still null
SingletonA still null
SingletonA still null
_instance :com.omt.sleepwait.Singleton@10c042ab
SingletonA still null
SingletonA still null
SingletonA still null
Both singleton are not same
Qui le istanze Singleton create da threadA e threadB NON sono uguali a causa del thread B che ha ricevuto modifiche per entrare nel blocco sincronizzato e dopo 500 millisecondi il threadA è partito dall'ultima posizione e ha creato un altro oggetto Singleton.
Dovrebbe essere chiamato dal blocco sincronizzato: il metodo wait ()
viene sempre chiamato dal blocco sincronizzato, ad esempio il metodo wait ()
deve bloccare l'oggetto monitorare prima dell'oggetto su cui viene chiamato. Ma il metodo sleep ()
può essere chiamato dall'esterno del blocco sincronizzato, cioè il metodo sleep ()
non ha bisogno di alcun oggetto monitor.
IllegalMonitorStateException: se viene chiamato il metodo wait ()
senza acquisire il blocco dell'oggetto di IllegalMonitorStateException
viene lanciato in fase di esecuzione, ma sleep ( )
non genera mai tale eccezione.
Appartiene a quale classe: wait ()
appartiene alla classe java.lang.Object
ma sleep () appartiene alla classe
java.lang.Thread
.
Chiamato su oggetto o thread: il metodo wait ()
viene chiamato sugli oggetti ma il metodo sleep ()
viene chiamato sui thread non sugli oggetti.
Stato del thread: quando viene chiamato il metodo wait ()
sull'oggetto, il thread che ha monitorato il monitor dell'oggetto passa dallo stato di esecuzione allo stato di attesa e può tornare allo stato eseguibile solo quando < Il metodo code> notify () o notifyAll ()
viene chiamato su quell'oggetto. E in seguito lo scheduler del thread pianifica che il thread passi dallo stato eseguibile a quello corrente.
quando sleep ()
viene chiamato sul thread, passa dallo stato di esecuzione allo stato di attesa e può tornare allo stato eseguibile quando il tempo di sospensione è scaduto.
Quando viene chiamato dal blocco sincronizzato: quando il metodo wait ()
viene chiamato thread lascia il blocco dell'oggetto. Ma il metodo sleep ()
quando viene chiamato dal blocco sincronizzato o dal thread del metodo non lascia il blocco degli oggetti.
Ulteriori informazioni Riferimento
Dalla pagina della documentazione di Oracle su wait () metodo di Object
:
public final void wait()
- Fa in modo che il thread corrente attenda fino a quando un altro thread invoca il metodo
notify ()
o il metodonotifyAll ()
per questo oggetto. In altre parole, questo metodo si comporta esattamente come se eseguisse semplicemente la chiamatawait (0)
. - Il thread corrente deve possedere il monitor di questo oggetto. Il thread rilascia la proprietà di questo monitor e attende fino a quando un altro thread non notifica ai thread in attesa che il monitor di questo oggetto si riattivi
- sono possibili interruzioni e svegli spurie
- Questo metodo deve essere chiamato solo da un thread proprietario del monitor di questo oggetto
Questo metodo genera
IllegalMonitorStateException
- se il thread corrente non è il proprietario del monitor dell'oggetto.InterruptedException
- se un thread ha interrotto il thread corrente prima o mentre il thread corrente era in attesa di una notifica. Lo stato interrotto del thread corrente viene cancellato quando viene generata questa eccezione.
Dalla pagina della documentazione di Oracle su Metodo sleep () della classe Thread
:
public static void sleep(long millis)
- Fa sospendere il thread attualmente in esecuzione (interrompe temporaneamente l'esecuzione) per il numero specificato di millisecondi, soggetto alla precisione e all'accuratezza dei timer e degli scheduler di sistema.
- Il thread non perde la proprietà di alcun monitor.
Questo metodo genera:
IllegalArgumentException
- se il valore di millis è negativoInterruptedException
- se qualche thread ha interrotto il thread corrente. Lo stato interrotto del thread corrente viene cancellato quando viene generata questa eccezione.
Altra differenza fondamentale:
wait ()
è un metodo non statico (metodo di istanza) a differenza del metodo statico sleep ()
(metodo di classe).
wait ()
viene fornito all'interno di un metodo sincronizzato
mentre sleep ()
viene fornito all'interno di un metodo non sincronizzato poiché il metodo wait ()
rilascia il blocco sull'oggetto ma sleep ()
o < code> yield () rilascia il lock ()
.
l'attesa con un valore di timeout può riattivarsi dopo il valore di timeout scaduto o avvisare quale è precedente (o interrompere anche), mentre un sonno si sveglia sul valore di timeout trascorso o interrompere qualunque sia precedente. wait () senza valore di timeout attenderà per sempre fino a quando non verrà notificato o interrotto
- Il metodo
wait (1000)
fa sospendere il thread corrente fino a un secondo .- Un thread potrebbe dormire meno di 1 secondo se riceve
notification ()
onotifyAll ()
chiamata di metodo.
- Un thread potrebbe dormire meno di 1 secondo se riceve
- La chiamata a
sleep (1000)
fa sospendere il thread corrente per esattamente 1 secondo .- Inoltre thread in sospensione non blocca alcuna risorsa . Ma aspettare thread lo fa.