私は最近stackoverflowで質問をし、その答えを見つけました。最初の質問は、ミューテックスまたはガベージコレクション以外のどのメカニズムがマルチスレッドJavaプログラムを遅くする可能性があるかということでした。
恐ろしいことに、HashMapがJDK1.6とJDK1.7の間で変更されていることに気づきました。これで、HashMapを作成するすべてのスレッドを同期させるコードのブロックができました。
JDK1.7.0_10のコード行は次のとおりです。
/**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);
どちらが呼び出すことになります
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));
}
他のJDKを見ると、これはJDK1.5.0_22またはJDK1.6.0_26には存在しません。
私のコードへの影響は甚大です。これにより、64スレッドで実行した場合、1スレッドで実行した場合よりもパフォーマンスが低下します。JStackは、ほとんどのスレッドがランダムのそのループでスピンすることにほとんどの時間を費やしていることを示しています。
だから私はいくつかのオプションがあるようです:
- HashMapを使用しないようにコードを書き直しますが、同様のものを使用します
- どういうわけかrt.jarをいじって、その中のハッシュマップを置き換えます
- どういうわけかクラスパスを台無しにするので、各スレッドは独自のバージョンのHashMapを取得します
これらのパスのいずれかを開始する前に(すべて非常に時間がかかり、影響が大きい可能性があるように見えます)、明らかなトリックを見逃したのではないかと思いました。あなたの誰かがオーバーフローした人々を積み重ねて、どちらがより良い道であるかを提案したり、おそらく新しいアイデアを特定したりできますか?
助けてくれてありがとう