Domanda

Il JavaDoc di ConcurrentHashMap dice questo:

  

Come Hashtable ma a differenza di HashMap, questa classe non permettono null da utilizzare come valore chiave o.

La mia domanda: perché

2 ° domanda: perché non permettere tabella hash nulla

Ho usato un sacco di HashMaps per la memorizzazione dei dati. Ma quando si passa a ConcurrentHashMap ho avuto più volte nei guai a causa di NullPointerExceptions.

È stato utile?

Soluzione

Dall'autore di ConcurrentHashMap se stesso (Doug Lea) :

  

Il motivo principale che i valori nulli non sono ammessi in ConcurrentMaps   (ConcurrentHashMaps, ConcurrentSkipListMaps) è che le ambiguità che   può essere solo a malapena tollerabile nelle mappe non concorrenti non può essere   sistemati. Il principale è che, se i rendimenti map.get(key) null, è   Non in grado di rilevare se il tasto mappe esplicitamente null vs la chiave non è   mappato. In una mappa non simultanea, è possibile controllare questa via   map.contains(key), ma in un unico concorrente, la mappa potrebbe essere cambiata   tra le chiamate.

Altri suggerimenti

Credo che sia, almeno in parte, per consentire di combinare containsKey e get in una singola chiamata. Se la mappa può contenere valori nulli, non c'è modo di dire se get sta tornando un nulla perché non c'era nessuna chiave per quel valore, o semplicemente perché il valore è nullo.

Perché è un problema? Perché non esiste un modo sicuro per farlo da soli. Prendere il seguente codice:

if (m.containsKey(k)) {
   return m.get(k);
} else {
   throw new KeyNotPresentException();
}

Poiché m è una mappa concorrente, chiave k può essere eliminato tra le chiamate containsKey e get, causando questo frammento di restituire un nulla che non era mai nella tabella, piuttosto che il KeyNotPresentException desiderato.

Normalmente si dovrebbe risolvere il sincronizzando, ma con una mappa concomitante che, naturalmente, non funzionerà. Da qui la firma per get doveva cambiare, e l'unico modo per farlo in modo compatibile all'indietro era di impedire all'utente di inserire valori nulli, in primo luogo, e continuare ad utilizzare che come segnaposto per "chiave non trovata".

Josh Bloch progettato HashMap; Doug Lea progettato ConcurrentHashMap. Spero che non sia diffamatorio. In realtà penso che il problema è che i null richiedono spesso involucro in modo che il vero nulla può stare non inizializzata. Se il codice cliente richiede i null allora può pagare il (certamente piccola) costo di confezionamento nulli per sé.

ConcurrentHashMap è thread-safe. Credo che non permettendo chiavi e valori nulli era una parte di fare in modo che sia thread-safe.

Credo che il seguente frammento di documentazione delle API dà un buon suggerimento: "Questa classe è completamente interoperabile con Hashtable in programmi basati sulla sua sicurezza filo ma non delle sue modalità di sincronizzazione."

Probabilmente Volevano solo fare ConcurrentHashMap pienamente compatibile / intercambiabili a Hashtable. E come Hashtable non consente chiavi e valori nulli ..

Non è possibile sincronizzare su un nullo.

Edit: Questo non è esattamente il motivo per cui in questo caso. Inizialmente ho pensato che ci fosse qualcosa di fantasia in corso con bloccaggio cose contro aggiornamenti simultanei o altrimenti utilizzando il monitor oggetto di rilevare se qualcosa è stato modificato, ma dopo aver esaminato il codice sorgente sembra mi sbagliavo - non si bloccano con un 'segmento' sulla base di una maschera di bit di l'hash.

In questo caso, ho il sospetto che lo hanno fatto per copiare Hashtable, e ho il sospetto Hashtable fatto perché nel mondo dei database relazionali, null! = Null, in modo da utilizzare un null come chiave non ha alcun significato.

Non credo che negare il riconoscimento di valore nullo è una corretta opzione. In molti casi, noi vogliamo fare inserire una chiave con valore nullo nella mappa con-corrente. Tuttavia, utilizzando ConcurrentHashMap, non possiamo farlo. Suggerisco che la venuta versione del JDK in grado di supportare questo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top