鉴于jdk1.6及更高版本中的HashMaps会导致multi=threading出现问题,我应该如何修复我的代码
我最近在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版本
在我开始走上这些道路之前(所有这些道路看起来都非常耗时且可能影响很大),我想知道我是否错过了一个明显的技巧。你们中是否有人能把溢出的人建议哪条路更好,或者确定一个新想法。
感谢您的帮助