8
votes

Est-il possible d'avoir plus de 32 serrures dans ConcourshashMap

J'ai lu Concurrenthashashmap fonctionne mieux dans Multi Filetage que la haquetable en raison d'avoir des serrures au niveau du seau plutôt que de la carte large. Il est possible à 32 verrouillages maximum par carte. Voulez-vous savoir pourquoi 32 et pourquoi pas plus de 32 serrures.


1 commentaires

Il y a un lien vers le code source dans ma réponse. Vous voudrez peut-être lire cela pour vous prouver que le maximum est, en fait, supérieur à 32 (c'est 2 ^ 16, ou 65 536 en tant que MHALLER noté).


4 Réponses :


5
votes

La valeur par défaut n'est pas 32, c'est 16. Et vous pouvez le remplacer par le Argument de constructeur Niveau de concurrence code> : xxx pré>

afin que vous puissiez faire: p>

Map<String, String> map = new ConcurrentHashmap<String, String)(128, 0.75f, 64);
  • InitialCapacité Code>: 16; LI>
  • loadFactory code>: 0.75F; li>
  • Concurrencydlevel code>: 16. li> ul> p>


5 commentaires

Oui, la valeur par défaut est 16, mais le maximum autorisé est 32. Et je veux savoir pourquoi est-ce 32.


Je ne sais pas où vous obtenez 32 de. Je regarde la source (Java 6) et nulle part-elle ne mentionne-t-elle pas 32.


Cet article est daté du 21 août 2003, il est donc préférable que Java 5 et, en tant que tel, c'était plus d'aperçu que tout. Toujours envisager des informations comme celle-ci dans le contexte de sa date. En cas de doute, allez à la source JDK.


@cletus Je me suis gratté la tête autour d'une question pendant un certain temps, j'ai regardé autour de moi, mais j'ai échoué à trouver la réponse. Je veux savoir ce qui va arriver si le Concurrencylose sera plus grand THA la capacité de la carte. Donc, par défaut les deux sont 16, ce qui signifie que chaque godet aura une serrure. Et si la capacité sera de 32 et Concurrencylose 16 qu'une serrure se tiendra sur 2 godets. Mais que se passe-t-il lorsque Concurrencydlevel est 32 et la capacité est 16?


2 serrures seront-elles tenues sur le même seau?



9
votes

Si vous parlez de Java Concurrenthashmap , la limite est arbitraire :

crée une nouvelle carte avec les mêmes mappages que la carte donnée. La carte est créée avec une capacité de 1,5 fois le nombre de mappages dans la carte donnée ou 16 (selon la valeur supérieure) et un facteur de charge par défaut (0,75) et une concurrence (16).

Si vous lisez le code source Il devient clair que le nombre maximum de segments est 2 ^ 16, qui devrait être plus que suffisant pour tout besoin imaginable dans l'avenir immédiat.

Vous avez peut-être pensé à certaines implémentations expérimentales alternatives, telles que celui-ci :

Cette classe prend en charge un niveau de concurrence prédéfinie filaire de 32. Cela permet un maximum de 32 mises et / ou de supprimer des opérations pour procéder simultanément.

Notez que, en général, les facteurs autres que l'efficacité de la synchronisation sont généralement les goulots d'étranglement lorsque plus de 32 threads tentent de mettre à jour un seul Concurrenthashmap . .


2 commentaires

Joli. Merci beaucoup John. Cette question se grattait ma tête depuis une semaine.


@John est-ce la limite du nombre maximal de lecteurs / écrivains / lecteurs + écrivains?



3
votes

Selon la source de Concurrenthashmap code>, le maximum autorisé est 65536 CODE>:

/**
 * 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;


1 commentaires

D'accord. J'ai sauté cela dans le Java Src. Merci Mike.



2
votes

Pour utiliser tout le niveau de concurrence par défaut de 16, vous devez disposer de 16 noyaux en utilisant la carte au même moment. Si vous avez 32 noyaux utilisant uniquement la carte 25% du temps, seuls 8 de 16 segments seront utilisés à la fois.

En résumé, vous devez avoir beaucoup de nœuds à utiliser tout en utilisant la même carte et ne rien faire beaucoup d'autre. Les vrais programmes font généralement autre chose que d'accéder à une carte.


5 commentaires

Peter, pouvez-vous me signaler un lien détaillé ou une référence pour de tels détails.


C'est juste logique comme je le vois. Le nombre de cœurs / hyper-threads que vous avez détermine le nombre de threads actifs que vous pouvez avoir; Appelez-le A. Si les threads passent un pourcentage de leur temps sur la carte, appelez-le à P. L'hypothèse est dont vous avez besoin autour de A * P segments (éventuellement de réduire la conflit), donc si vous avez 4 cœurs et qu'il dépense 25% de Le temps sur la carte (ce serait très élevé pour un programme qui fonctionne utile), vous avez besoin d'environ 4 segments de 25%, c'est-à-dire 1. Vous pouvez faire les mathématiques. Pour vous, le nombre de cœurs et le pourcentage de temps vous attendez d'utiliser la carte.


Frapper une cache Mlle fera caution du fil / noyau actuel à autre chose, ce n'est pas aussi simple.


Les misses de cache se produisent très souvent, je ne crois pas que cela se traduit par un commutateur de contexte. Qu'entendez-vous par «caution hors du fil actuel / noyau à autre chose»?


@Peterlawrey est cette limite le nombre maximal de filets de lecteur / nombre maximum de threads de Writer / Max (lecteur + écrivain)?