2013-10-07 16 views
5

Ho letto che le hashtable sono thread-safe perché è sincronizzato. considera questo snippet di codicehashtable e sincronizzazione in Java

if(!hashtable.contains(key)){ 
hashtable.put(key,value); 
} 

Le operazioni su hashtable potrebbero non essere sincronizzate. ad esempio, se Thread t1 accede a hastable e controlla la chiave e allo stesso tempo Thread t2 controlla la chiave, prima che t1 esegua put. ora due thread si trovano all'interno del blocco if e sovrascrive il valore-chiave.

quindi è necessario il blocco sincronizzato.

synchronized { 
if(!hashtable.contains(key)){ 
    hashtable.put(key,value); 
    } 
} 

Questa comprensione è corretta? o è hastables sicuro sulle operazioni eseguite su hastables. Ho avuto questo dubbio mentre stavo leggendo questo post on race condition

+0

Sì, è corretto. – SJuan76

risposta

9

Hai ragione, hai bisogno del blocco synchronized. I metodi Hashtable's sono synchronized, ma è ancora possibile avere una corsa quando si chiamano più metodi al di fuori di un blocco synchronized. La sincronizzazione integrata impedisce problemi quando due thread chiamano put allo stesso tempo, ad esempio.

Si potrebbe anche voler guardare in ConcurrentHashMap

3

Hashtable metodi sono sincronizzati, ma che fornisce solo una protezione a livello di metodo contro le condizioni di gara. (Quindi uno — a differenza di un — non verrà danneggiato internamente se più thread stanno tentando contemporaneamente di modificare i dati.) È solo in questo senso che Hashtable è thread-safe.

HashtableConcurrentHashMap fornirà sincronizzazione a livello superiore, che è solitamente * ciò che è necessario quando si eseguono operazioni multi-step. È necessario un blocco esterno synchronized, quindi è possibile utilizzare anche l'overhead inferiore HashMap anziché Hashtable.

  * Come Jeff Storey sottolinea, ConcurrentHashMap ha un metodo putIfAbsent che fa esattamente quello che stai facendo nel codice. Per altre operazioni multi-passo, ConcurrentHashMap può o non può avere un metodo che fa ciò che ti serve atomicamente.

+1

'ConcurrentHashMap' ha un metodo' putIfAbsent' che controllerà atomicamente il contenimento della chiave e lo inserirà se non esiste –

+0

@JeffStorey - Sì, ho dimenticato questo. Grazie. Aggiornerò la mia risposta di conseguenza. Tuttavia, per altre operazioni a più fasi, potrebbe essere necessaria la sincronizzazione esterna. –