38 votes

Mise en œuvre de Java ConcurrentHashMap

Je regardais le code source du ConcurrentHashMap de Java et j'ai trouvé cette ligne de code :

/*
 * The maximum number of times to tryLock in a prescan before possibly blocking on acquire in   
 * preparation for a locked segment operation. On multiprocessors, using a bounded number of  
 * retries maintains cache acquired while locating nodes.
 */
static final int MAX_SCAN_RETRIES =
              Runtime.getRuntime().availableProcessors() > 1 ? 64 : 1

El MAX_SCAN_RETRIES est utilisé pour rechercher des entrées lors de l'acquisition du verrou. Ma question est de savoir comment le nombre 64 déterminé pour une machine multiprocesseur ? Quelqu'un connaît-il la théorie derrière ce nombre 64 ?

9voto

Kevin Sitze Points 641

Lorsque l'on traite les tentatives de verrouillage sur plusieurs CPU, il faut trouver un équilibre entre la tentative d'obtenir le verrou rapidement (rotation) et le fait de permettre au CPU de passer à un autre thread pour éviter de perdre du temps à tourner sur un verrou qui ne sera pas libéré bientôt. Le nombre réel de rotations autorisées pour qu'un CPU tente d'obtenir un verrou est fortement affecté par la vitesse réelle du système global ainsi que par la quantité de code qui s'exécute généralement dans la section critique.

Cette question a des racines profondes dans le problème de l'arrêt et de nombreux autres problèmes liés à la conception du système d'exploitation sur les systèmes SMP en ce qui concerne l'optimisation de la concurrence. Ce type de choix de conception est généralement résolu par une approche par essais et erreurs dans de nombreuses applications ; cependant, le choix de 64 me semble être un choix arbitraire de la part de l'implémenteur (le nombre est une puissance de deux).

Malheureusement, ce code particulier est à la fois bogué et limitatif. Il est bogué dans la mesure où la documentation relative à availableProcessors indique "Cette valeur peut changer au cours d'une invocation particulière de la machine virtuelle", ce qui peut entraîner un trop grand nombre de rotations du verrou (si le compte passe de > 1 à = 1) ou un nombre insuffisant (dans le cas inverse). Il est limitatif dans la mesure où un développeur qui a vraiment besoin de régler la concurrence dans son application n'a aucune possibilité de le faire puisque MAX_SCAN_RETRIES est définitif (bien que certaines astuces puissent être jouées avec la réflexion).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X