J'ai récemment posé une question dans stackoverflow, puis trouvé la réponse. La question initiale était Que des mécanismes autres que des mutexs ou la collecte des ordures peut ralentir mon multi-thread programme java?
J'ai découvert à ma grande horreur, que la table de hachage a été modifié entre JDK1.6 et JDK1.7. Il a maintenant un bloc de code qui provoque tous les threads création HashMaps à synchroniser.
La ligne de code dans JDK1.7.0_10 est
/**A randomizing value associated with this instance that is applied to hash code of keys to make hash collisions harder to find. */
transient final int hashSeed = sun.misc.Hashing.randomHashSeed(this);
Qui finit par appel
protected int next(int bits) {
long oldseed, nextseed;
AtomicLong seed = this.seed;
do {
oldseed = seed.get();
nextseed = (oldseed * multiplier + addend) & mask;
} while (!seed.compareAndSet(oldseed, nextseed));
return (int)(nextseed >>> (48 - bits));
}
La recherche dans d'autres Jdk, je trouve que ce n'est pas présente dans JDK1.5.0_22, ou JDK1.6.0_26.
L'impact sur mon code est énorme. Il fait en sorte que lorsque je l'exécute sur 64 threads, je reçois de moins bonnes performances que lorsque je l'exécute sur 1 fil. Un JStack montre que la plupart des threads passent la plupart de leur temps à tourner en boucle dans un ordre Aléatoire.
Donc, il me semble avoir quelques options:
- Réécrire mon code pour que je n'utilise pas la table de hachage, mais utiliser quelque chose de similaire
- En quelque sorte, s'amuser avec les rt.jar et remplacer la table de hachage à l'intérieur
- Mess avec le chemin de classe d'une certaine manière, de sorte que chaque thread possède sa propre version de la table de hachage
Avant de me lancer dans un de ces chemins (très chronophages et potentiellement un impact élevé), je me demandais si j'avais raté un truc évident. Pouvez-vous tout de débordement de pile personnes suggèrent ce qui est le meilleur chemin, ou peut-être d'identifier une nouvelle idée.
Merci pour l'aide