최근에 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은 대부분의 스레드가 Random에서 해당 루프에서 회전하는 데 대부분의 시간을 소비하고 있음을 보여줍니다.
그래서 몇 가지 옵션이있는 것 같습니다.
- HashMap을 사용하지 않고 비슷한 것을 사용하도록 코드를 다시 작성하십시오.
- 어떻게 든 rt.jar을 엉망으로 만들고 그 안의 해시 맵을 교체하십시오.
- 어떻게 든 클래스 경로가 혼란 스럽기 때문에 각 스레드는 자체 버전의 HashMap을 얻습니다.
이러한 경로를 시작하기 전에 (모두 시간이 많이 걸리고 잠재적으로 큰 영향을 미치는 것처럼 보임) 분명한 트릭을 놓쳤는 지 궁금했습니다. 스택 오버플로 사람들 중 누구든지 더 나은 경로를 제안하거나 새로운 아이디어를 식별 할 수 있습니까?
도와 주셔서 감사합니다