Gần đây tôi đã đưa ra một câu hỏi trong stackoverflow, sau đó tìm thấy câu trả lời. Câu hỏi ban đầu là Cơ chế nào ngoài mutexs hoặc thu gom rác có thể làm chậm chương trình java đa luồng của tôi?
Tôi kinh hoàng phát hiện ra rằng HashMap đã được sửa đổi giữa JDK1.6 và JDK1.7. Bây giờ nó có một khối mã khiến tất cả các luồng tạo HashMaps đồng bộ hóa.
Dòng mã trong JDK1.7.0_10 là
/**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);
Kết thúc cuộc gọi
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));
}
Tìm kiếm trong các JDK khác, tôi thấy điều này không có trong JDK1.5.0_22 hoặc JDK1.6.0_26.
Tác động đến mã của tôi là rất lớn. Nó làm cho nó để khi tôi chạy trên 64 luồng, tôi nhận được hiệu suất kém hơn so với khi tôi chạy trên 1 luồng. Một JStack cho thấy rằng hầu hết các chủ đề đang dành phần lớn thời gian để quay trong vòng lặp đó ở chế độ Ngẫu nhiên.
Vì vậy, tôi dường như có một số lựa chọn:
- Viết lại mã của tôi để tôi không sử dụng HashMap mà sử dụng thứ gì đó tương tự
- Bằng cách nào đó, hãy làm lộn xộn với rt.jar và thay thế bản đồ băm bên trong nó
- Lộn xộn với đường dẫn lớp bằng cách nào đó, vì vậy mỗi luồng có phiên bản HashMap của riêng mình
Trước khi bắt đầu bất kỳ con đường nào trong số này (tất cả đều trông rất tốn thời gian và có khả năng ảnh hưởng cao), tôi tự hỏi liệu mình có bỏ lỡ một mẹo rõ ràng nào không. Mọi người trong số các bạn có thể đề xuất con đường nào tốt hơn không, hoặc có thể xác định một ý tưởng mới.
Cảm ơn đã giúp đỡ