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?

È stato utile?

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 con sleep () , il sistema operativo ha vinto & # 8217; t   prova anche a pianificare la tua attività a meno che qualcuno non chiami notification () (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 un yield () 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
  1. wait () rilascia il blocco.
  2. wait () è il metodo della classe Object .
  3. wait () è il metodo non statico - void wait pubblico () genera InterruptedException {// ...}
  4. wait () deve essere notificato con i metodi notification () o notificationAll () .
  5. Il metodo
  6. wait () deve essere chiamato da un loop per gestire i falsi allarmi.

  7. Il metodo
  8. wait () deve essere chiamato dal contesto sincronizzato (cioè metodo o blocco sincronizzato), altrimenti genererà IllegalMonitorStateException

sleep ()

    Il metodo
  1. sleep () non rilascia il blocco.
  2. sleep () è il metodo della classe java.lang.Thread .
  3. sleep () è il metodo statico - sleep vuoto statico pubblico (long millis, int nanos) genera InterruptedException {// ...}
  4. dopo il periodo di tempo specificato, sleep () è completato.
  5. sleep () è meglio non chiamare dal loop (ovvero vedi il codice qui sotto ).
  6. 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    
}

 transizione del thread a diversi stati del thread

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:

  1. 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)
  2. 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)
  3. 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)
  4. Condizioni di sveglia :
    • wait (): fino alla chiamata notification (), notifyAll () dall'oggetto
    • sleep (): fino almeno alla scadenza o alla chiamata di interruzione
  5. 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 da Object e sleep () è un metodo statico di Discussione .

  • La differenza principale è che wait () rilascia il blocco mentre sleep () non rilascia alcun blocco durante l'attesa.

  • wait () viene utilizzato per la comunicazione tra thread mentre sleep () viene utilizzato per introdurre una pausa nell'esecuzione, in generale.

  • wait () dovrebbe essere chiamato dall'interno sincronizzato oppure otteniamo un IllegalMonitorStateException , mentre sleep () può essere chiamato ovunque.

  • Per ricominciare una discussione da wait () , devi chiamare notify () o notificationAll () . Per quanto riguarda sleep (), 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 chiama t.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 " ,   come sleep () , ma con una svolta. L'attesa viene chiamata su un oggetto, non a   filo; chiamiamo questo oggetto l'oggetto "lock". " Prima di lock.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 chiama lock.notify () . Questo sveglia l'originale,   filo in attesa. Fondamentalmente, wait () / notification () è come    sleep () / 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

I metodi

?? 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 chiama notifica o NotifyAll .

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-/

Metodo

wait ().

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.

  1. wait () è un metodo della classe Object .
    sleep () è un metodo della classe Thread .

  2. sleep () consente al thread di passare allo stato sleep per x millisecondi.
    Quando un thread passa allo stato di sospensione non rilascia il blocco .

  3. wait () consente al thread di rilasciare il blocco e passa allo stato sospeso .
    Questo thread sarà attivo quando un metodo notification () o notifAll () è chiamato per lo stesso oggetto.

Una potenziale grande differenza tra sospensione / interruzione e attesa / notifica è quella

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.

Il metodo

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.

Il metodo

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:

  1. Impone la centralizzazione. Permette di coordinare la comunicazione tra un gruppo di thread con un singolo oggetto condiviso. Questo semplifica molto il lavoro.

  2. Applica la sincronizzazione. Perché fa sì che il programmatore avvolga la chiamata in attesa / notifica in un blocco sincronizzato.

  3. È 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:

  1. Principale : contiene il metodo principale e due thread.
  2. 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()
  1. Fa in modo che il thread corrente attenda fino a quando un altro thread invoca il metodo notify () o il metodo notifyAll () per questo oggetto. In altre parole, questo metodo si comporta esattamente come se eseguisse semplicemente la chiamata wait (0) .
  2. 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
  3. sono possibili interruzioni e svegli spurie
  4. Questo metodo deve essere chiamato solo da un thread proprietario del monitor di questo oggetto

Questo metodo genera

  1. IllegalMonitorStateException - se il thread corrente non è il proprietario del monitor dell'oggetto.

  2. 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)
  1. 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.
  2. Il thread non perde la proprietà di alcun monitor.

Questo metodo genera:

  1. IllegalArgumentException - se il valore di millis è negativo

  2. InterruptedException - 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 .
  • 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.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top