No, si stanno perdendo i vantaggi di ConcurrentHashMap
facendo quello. Si può anche utilizzare un HashMap
con synchronized
o synchronizedMap()
per bloccare l'intera tabella (che è quello che si fa quando avvolgendo le operazioni in synchronized
, dal momento che il monitor implicita è l'intera istanza di oggetto.)
Lo scopo di ConcurrentHashMap
è quello di aumentare la velocità effettiva del codice concorrente consentendo letture/scritture simultanee sulla tabella senza bloccare l'intera tabella. La tabella supporta questo internamente utilizzando il lock striping (più blocchi invece di uno, con ogni blocco assegnato a un set di bucket hash - vedi Java Concurrency in Practice di Goetz et al).
Una volta che si utilizza ConcurrentHashMap
, tutti i metodi mappa standard (put()
, remove()
, etc.) diventano atomica in virtù del blocco striping ecc nell'implementazione. Gli unici compromessi sono che metodi come size()
e isEmpty()
potrebbero non restituire risultati accurati, poiché l'unico modo in cui potrebbero essere per tutte le operazioni bloccare l'intera tabella.
L'interfaccia ConcurrentMap
interface aggiunge anche nuove operazioni composite atomica come putIfAbsent()
(mettere qualcosa solo se la chiave non è già nella mappa), remove()
accettando sia chiave e il valore (rimuovere una voce solo se il suo valore è uguale a un parametro che si passa), ecc Queste operazioni usati per richiedere il blocco l'intera tabella perché avevano bisogno due chiamate di metodo per realizzare (ad esempio putIfAbsent()
avrebbe bisogno chiamate a entrambi containsKey()
e put()
, avvolto all'interno di un blocco synchronized
, se si stesse utilizzando un Map
implementazione standard.) una volta di nuovo, si ottiene un maggiore throughput utilizzando questi metodi, evitando di bloccare l'intera tabella.
fonte
2014-09-23 15:25:10