मैंने हाल ही में स्टैकओवरफ्लो में एक सवाल उठाया, फिर जवाब मिला। प्रारंभिक प्रश्न यह था कि म्यूटेक्स या कचरा संग्रह के अलावा अन्य तंत्र क्या मेरे बहु-थ्रेडेड जावा प्रोग्राम को धीमा कर सकते हैं?
मुझे अपने आतंक का पता चला कि 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));
}
अन्य JDKs में देखते हुए, मुझे लगता है कि यह JDK1.5.0_22, या JDK1.6.0_26 में मौजूद नहीं है।
मेरे कोड पर प्रभाव बहुत बड़ा है। यह ऐसा करता है कि जब मैं 64 थ्रेड्स पर चलता हूं, तो जब मैं 1 थ्रेड पर चलता हूं तो मुझे कम प्रदर्शन मिलता है। एक JStack से पता चलता है कि अधिकांश धागे रैंडम में उस लूप में घूमने में अपना अधिकांश समय बिता रहे हैं।
इसलिए मुझे लगता है कि कुछ विकल्प हैं:
- मेरे कोड को फिर से लिखें ताकि मैं हाशपैप का उपयोग न करूं, लेकिन कुछ इसी तरह का उपयोग करें
- किसी तरह rt.jar के साथ गड़बड़ करें, और उसके अंदर हैशमैप को बदल दें
- किसी तरह क्लास पथ के साथ मेस करें, इसलिए प्रत्येक थ्रेड को हाशपैप का अपना संस्करण मिलता है
इससे पहले कि मैं इनमें से किसी भी मार्ग को शुरू करूं (सभी को बहुत समय लगता है और संभावित रूप से उच्च प्रभाव दिखता है), मुझे आश्चर्य होता है कि क्या मैं एक स्पष्ट चाल से चूक गया हूं। क्या आप में से कोई भी अतिप्रवाह लोगों को ढेर कर सकता है जो बेहतर पथ है, या शायद एक नए विचार की पहचान करता है।
सहायता के लिए धन्यवाद