我最近在stackoverflow中提出了一个问题,然后找到了答案。最初的问题是除了互斥锁或垃圾回收之外,还有哪些机制会减慢我的多线程 Java 程序的速度?
我惊恐地发现 HashMap 已经在 JDK1.6 和 JDK1.7 之间进行了修改。它现在有一个代码块,可以使所有创建 HashMaps 的线程同步。
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
- 不知何故弄乱了类路径,所以每个线程都有自己的 HashMap 版本
在我开始使用这些路径中的任何一条之前(所有这些路径看起来都非常耗时并且可能会产生很大的影响),我想知道我是否错过了一个明显的技巧。你们中的任何人都可以堆栈溢出的人建议哪个是更好的路径,或者可能确定一个新想法。
谢谢您的帮助