एक Collections.synchronizedMap()
में ताला के बीच का अंतर और एक ConcurrentHashMap
है थ्रेड एक्स Collections.synchronizedMap()
पर एक विधि को कॉल करता है, अन्य सभी धागे Collections.synchronizedMap()
पर किसी भी विधि को कॉल करने से अवरुद्ध कर दिए जाएंगे जब तक कि थ्रेड एक्स उस विधि से वापस न आए)।
ए ConcurrentHashMap
में ताले की एक चर संख्या है (डिफ़ॉल्ट 16 है) प्रत्येक ConcurrentHashMap
में चाबियों का एक सेगमेंट रखता है। तो 160 कुंजी के साथ ConcurrentHashMap
के लिए, प्रत्येक लॉक 10 तत्वों की रक्षा करेगा। इसलिए, एक कुंजी पर चलने वाली विधियां (get
, put
, set
, आदि ...) केवल उस कुंजी पर चलने वाली अन्य विधियों तक पहुंच को लॉक करें जहां कुंजी एक ही सेगमेंट में हैं। उदाहरण के लिए, यदि थ्रेड एक्स put(0, someObject)
पर कॉल करता है, और फिर थ्रेड वाई put(10, someOtherObject)
कॉल करता है तो वे कॉल एक साथ निष्पादित कर सकते हैं, और थ्रेड वाई को थ्रेड एक्स के लिए put(0, someObject)
से वापस आने की प्रतीक्षा नहीं करनी पड़ती है। एक उदाहरण नीचे प्रदान किया गया है।
इसके अतिरिक्त, size()
और isEmpty()
जैसी कुछ विधियों की सुरक्षा नहीं की जाती है। हालांकि यह अधिक समवर्तीता के लिए अनुमति देता है, इसका मतलब है कि वे दृढ़ता से संगत नहीं हैं (वे उस स्थिति को प्रतिबिंबित नहीं करेंगे जो समवर्ती रूप से बदल रहा है)।
public static void main(String[] args) {
ConcurrentHashMap<Integer, Object> map = new ConcurrentHashMap<>(160);
new Thread(new Runnable() {
@Override
public void run() {
map.put(0, "guarded by one lock");
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
map.put(10, "guarded by another lock");
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
// could print 0, 1, or 2
System.out.println(map.count());
}
}.start();
}
स्रोत
2013-04-22 16:22:58
ठीक है, मैं समझता हूं। लेकिन क्या होगा यदि दो या दो से अधिक धागे उप-सरणी {0,63} में सभी को संशोधित करने का प्रयास कर रहे हैं? – GedankenNebel
फिर पहली बार पहली बार सेवा की जाती है - ताला हासिल करने वाला पहला धागा इसके परिवर्तन करता है, फिर जब यह दूसरे धागे को समाप्त करता है तो इसके परिवर्तन होते हैं। 'ConcurrentHashMap' में' प्रतिस्थापन 'जैसी विधियां हैं ताकि यह सुनिश्चित किया जा सके कि दूसरा थ्रेड अनजाने में पहले थ्रेड के परिवर्तनों को ओवरराइट नहीं करता है। –
मुझे नहीं लगता कि यह वास्तव में "पहली बार पहली बार सेवा की जाती है," जैसा कि मैं समझता हूं (मेरे पास सटीक उद्धरण नहीं है, लेकिन मैंने इसे अभ्यास में जावा कंसुरेंसी से सीखा है) निष्पक्षता केवल तब ही गारंटी दी जाती है जब यह स्पष्ट हो, रचनाकारों की तरह अलग-अलग स्पष्ट 'लॉक' कार्यान्वयन के लिए, जैसे 'रीन्टेंट्रॉक लॉक', या 'ऐरेब्लॉकिंग क्यूयू' जैसी पंक्तियां। (मुझे पता है कि यह एक पुराना धागा है, क्षमा करें) – Marcelo