2009-11-20 7 views

risposta

41

Perché, si attende un determinato oggetto (o in particolare il suo monitor) per utilizzare questa funzionalità.

Penso che potresti sbagliare su come funzionano questi metodi. Non sono semplicemente a livello di granularità del thread, vale a dire che è non un caso di chiamare solo wait() e essere svegliato dalla prossima chiamata a notify(). Piuttosto, si chiama sempre wait() su un oggetto specifico e si riattiva solo tramite chiamate a notifysu quell'oggetto.

Questo è buono perché altrimenti le primitive della concorrenza non sarebbero in scala; equivarrebbe a disporre di spazi dei nomi globali, poiché qualsiasi chiamata a notify() in qualsiasi punto del programma potrebbe compromettere lo codice simultaneo in quanto risveglierebbero qualsiasi thread che blocca su una chiamata wait(). Da qui il motivo per cui li chiami su un oggetto specifico; fornisce un contesto in cui la coppia wait-notify può operare, quindi quando chiami myBlockingObject.notify(), su un oggetto privato, puoi essere certo che sveglierai solo i thread che hanno chiamato i metodi di attesa nella tua classe. Alcuni thread Spring che potrebbero essere in attesa su un altro oggetto non verranno riattivati ​​da questa chiamata e viceversa.

Edit: O per affrontare da un altro punto di vista - mi aspetto dalla tua domanda si pensava si otterrebbe un handle per il thread in attesa e chiamare notify() su quel filo per svegliarlo. Il motivo per cui non è fatto in questo modo, è che dovresti fare un sacco di pulizie da solo. Il thread in attesa avrebbe dovuto pubblicare un riferimento a se stesso da qualche parte che altri thread potevano vederlo; questo dovrebbe essere correttamente sincronizzato per rafforzare la coerenza e la visibilità. E quando vuoi risvegliare un thread devi ottenere questo riferimento, risvegliarlo e rimuoverlo da dove lo leggi. C'è molto più impalcatura manuale e molte più possibilità di sbagliare (specialmente in un ambiente concorrente) rispetto alla semplice chiamata myObj.wait() nel thread dormiente e quindi myObj.notify() nel thread waker.

+7

Questo non inizia a rispondere perché è possibile attendere su QUALSIASI oggetto. Perché non c'era una specifica classe o tipo di blocco? O forse un'interfaccia marcatore? – mjaggard

+0

"... potenziale per incasinare qualsiasi codice simultaneo mentre risvegliano qualsiasi thread che blocca su una chiamata wait() ..."Va bene fintanto che" incasinare "significa" limitare le prestazioni ". In realtà non dovrebbe interrompere nulla perché un _always_ chiama wait() in un ciclo finché la condizione che si sta aspettando diventa vera. –

8

Perché solo un thread alla volta può possedere il monitor di un oggetto e questo monitor è ciò che i thread sono in attesa o notifica. Se leggi lo javadoc per Object.notify() e Object.wait() è descritto in dettaglio.

+0

Hey Grazie Taylor – Bhupi

+0

Prego. –

10

Il motivo più semplice e ovvio è che qualsiasi oggetto (non solo un thread) può essere il monitor per un thread. L'attesa e la notifica vengono richiamate sul monitor . Il thread in esecuzione controlla con il monitor. Quindi i metodi wait e notify sono in Object e non Thread

0

Leggi here per una spiegazione di attesa e notifica.

Sarebbe meglio evitare questi tuttavia nelle applicazioni e utilizzare il nuovo pacchetto java.util.concurrent.

1

Il meccanismo di sincronizzazione implica un concetto - monitor di un oggetto. Quando viene chiamato wait(), il monitor viene richiesto e l'ulteriore esecuzione viene sospesa fino a quando non viene acquisito il monitoraggio o si verifica InterruptedException. Quando viene chiamato notify(), il monitor viene rilasciato.

Prendiamo uno scenario se wait() e notify() sono stati inseriti nella classe Thread anziché nella classe Object. A un punto del codice, viene chiamato currentThread.wait() e quindi si accede a un oggetto anObject.

//......... 
currentThread.wait(); 
anObject.setValue(1); 
//......... 

Quando currentThread.wait() viene chiamato, monitor currentThread è richiesto e nessun ulteriore esecuzione è fatto fino a quando il monitor è acquisito o InterruptedException verifica. Ora, mentre è in stato di attesa, se un metodo di un altro oggetto residente in currentThread viene chiamato da un altro thread, viene bloccato anche se il metodo chiamato foo() non accede a anObject. Se il primo metodo wait() è stato chiamato su anObject, invece del thread stesso, altre chiamate di metodo (non accedendo a anObject) su oggetti che risiedono nello stesso thread non si bloccherebbero.

Così i metodi wait() e notify() sulla classe Object (o le sue sottoclassi) forniscono una maggiore concorrenza ed è per questo che questi metodi si trovano nella classe Object, non nella classe Thread.

0

Io porrò in un modo semplice:

Per chiamare wait() o notify() è necessario possedere il monitor oggetto - questo significa attendere() o notifica() ha bisogno di essere presenti nel sincronizzato bloccare

synchronized(monitorObj){ 
monitorObj.wait() or even notify 
} 

Questo è il motivo per cui questi metodi sono presenti in classe dell'oggetto

0

Infatti, questi metodi sono per la comunicazione tra filo e interthreadcommunication avviene utilizzando serrature, ma serrature sono associati con objects.hence è in classe di oggetti.

0

I metodi Wait e Notify sono utilizzati per comunicare tra due thread in Java. Quindi la classe Object è il posto giusto per renderli disponibili per ogni oggetto in Java.

Un altro motivo è che i blocchi sono resi disponibili in base all'oggetto. I thread devono essere bloccati e aspettano il blocco, non sanno quali thread detengono il blocco, invece sanno solo che il blocco è trattenuto da alcuni thread e dovrebbero attendere il lock invece di sapere quale thread è all'interno del blocco sincronizzato e chiedere loro di rilasciare lock

1

Alcune delle altre risposte usano la parola "monitor", ma nessuna spiega cosa significa.

Il nome "monitor" è stato coniato nel lontano anni '70 e si riferiva a un oggetto che aveva il proprio blocco intrinseco e al meccanismo di attesa/notifica associato. https://en.wikipedia.org/wiki/Monitor_%28synchronization%29

Vent'anni più tardi, ci fu un breve momento nel tempo in cui desktop, computer multi-processore erano nuove, ed era di moda pensare che il modo giusto per progettare software per loro sarebbe di creare programmi orientati agli oggetti in quale ogni oggetto era un monitor.

Si scopre che non è stata un'idea così utile, ma quel breve momento sembra essere esattamente quando il linguaggio di programmazione Java è stato inventato.