Domanda

Ho letto ConcurrentHashMap funziona meglio in multi threading di Hashtable a causa di avere le serrature a livello secchio piuttosto che mappare blocco di larghezza. E 'al massimo 32 serrature possibile per mappa. Volete sapere perché 32 e perché non più di 32 blocchi.

È stato utile?

Soluzione

Se si sta parlando del ConcurrentHashMap Java, allora il limite è arbitraria :

  

Crea una nuova mappa con le stesse mappature come la mappa dato. La mappa viene creata con una capacità di 1,5 volte il numero di mapping nella mappa dato o 16 (il valore maggiore), e un fattore di carico di default (0,75) e concurrencyLevel (16).

Se leggete la codice sorgente diventa chiaro che il numero massimo di segmenti è 2 ^ 16, che dovrebbe essere più che sufficiente per qualsiasi esigenza concepibile nell'immediato futuro.

Si può avere pensato di alcune implementazioni sperimentali alternativi, come questa :

  

Questa classe supporta un livello preimpostato concorrenza cablata di 32. Questo consente un massimo di 32 put e / o rimuovere operazioni procedere contemporaneamente.

Si noti che, in generale, fattori diversi efficienza sincronizzazione sono di solito strozzature quando più di 32 fili stanno cercando di aggiornare un singolo ConcurrentHashMap.

Altri suggerimenti

Il default non è 32, è 16. E si può sovrascrivere con il argomento del costruttore concurrency level :

public ConcurrentHashMap(int initialCapacity,
                         float loadFactor,
                         int concurrencyLevel)

in modo da poter fare:

Map<String, String> map = new ConcurrentHashmap<String, String)(128, 0.75f, 64);

per cambiare a 64. Le impostazioni predefinite sono (come di Java 6u17):

  • initialCapacity: 16;
  • loadFactory: 0.75f;
  • concurrencyLevel:. 16

Secondo la fonte della ConcurrentHashMap, il massimo consentito è 65536:

/**
 * The maximum number of segments to allow; used to bound
 * constructor arguments.
 */
static final int MAX_SEGMENTS = 1 << 16; // slightly conservative

public ConcurrentHashMap(int initialCapacity,
                         float loadFactor, int concurrencyLevel) {
    if (concurrencyLevel > MAX_SEGMENTS)
        concurrencyLevel = MAX_SEGMENTS;

Per usare tutto il livello di concorrenza predefinito di 16 è necessario avere 16 core utilizzando la mappa nello stesso momento. Se si dispone di 32 core solo utilizzando la mappa 25% del tempo di allora solo 8 dei 16 segmenti saranno utilizzati in una sola volta.

In sintesi, è necessario disporre di un sacco di nuclei tutti utilizzando la stessa mappa e non fare niente molto altro. veri e propri programmi di solito fanno qualcosa di diverso accesso con un solo programma.

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