Se questo è tutto ciò che è nel blocco sincronizzata allora è un antipattern, il punto di sincronizzazione è di fare qualcosa all'interno del blocco, impostando qualche condizione, quindi chiamare notify
o notifyAll
di svegliarsi una o più thread in attesa.
Quando si utilizza attesa e comunicare è necessario utilizzare una variabile di condizione, vedi this Oracle tutorial:
Nota: invocano sempre attesa all'interno di un ciclo che i test per la condizione di essere aspettato. Non dare per scontato che l'interruzione riguardasse la particolare condizione che si stava aspettando o che la condizione fosse ancora vera.
Non si dovrebbe supporre che hai ricevuto una notifica solo perché un filo esce da una chiamata a Object # aspettare, per diverse ragioni:
Quando si chiama la versione di attesa che assume un valore di timeout non c'è modo di sapere se l'attesa è terminata a causa della ricezione di una notifica o della scadenza.
È necessario tenere conto della possibilità che un thread si possa riattivare dall'attesa senza aver ricevuto una notifica (il "wakeful spurio").
Il thread in attesa che riceve una notifica deve ancora riacquisire il blocco che ha abbandonato quando ha iniziato ad attendere, non c'è nessun collegamento atomico di questi due eventi; nell'intervallo tra la notifica e la riacquisizione del blocco, un altro thread può agire e, eventualmente, modificare lo stato del sistema in modo che la notifica non sia valida.
È possibile avere un caso in cui il thread di notifica agisce prima che qualsiasi thread sia in attesa in modo che la notifica non abbia alcun effetto. Supponendo che un thread entri in attesa prima che l'altro thread lo notifichi è pericoloso, se hai torto il thread in attesa si bloccherà indefinitamente.
Quindi una notifica di per sé non è abbastanza buono, si finisce per indovinare sul fatto che una notifica è accaduto quando l'attesa/notifica API non ti dà abbastanza informazioni per sapere cosa sta succedendo. Anche se altri lavori che il thread di notifica sta facendo non richiede la sincronizzazione, l'aggiornamento della variabile condizione lo fa; dovrebbe esserci almeno un aggiornamento della variabile di condizione condivisa nel blocco sincronizzato.
fonte
2011-09-30 16:07:56
I * credo * questo è più appropriato per http://codereview.stackexchange.com – BalusC
materiale di lettura: http://stackoverflow.com/questions/442564/avoid-synchronizedthis-in- java – claymore1977
Ti stai chiedendo se la sincronizzazione è necessaria prima della chiamata a 'notify()'? Il thread ** deve contenere il monitor dell'oggetto quando chiama 'notify()', quindi è necessario in generale. –