जावा सिंक्रनाइज़ेशन ब्लॉक .class के लिए


103

इस जावा कोड का क्या अर्थ है? क्या यह सभी वस्तुओं पर ताला लगाएगा MyClass?

synchronized(MyClass.class) {
   //is all objects of MyClass are thread-safe now ??
}

और उपरोक्त कोड इस से कैसे भिन्न होता है:

synchronized(this) {
   //is all objects of MyClass are thread-safe now ??
}

जवाबों:


144

स्निपेट synchronized(X.class)मॉनिटर के रूप में वर्ग उदाहरण का उपयोग करता है। जैसा कि केवल एक वर्ग उदाहरण है (रनटाइम के दौरान कक्षा मेटाडेटा का प्रतिनिधित्व करने वाला ऑब्जेक्ट) एक धागा इस ब्लॉक में हो सकता है।

synchronized(this)ब्लॉक उदाहरण के साथ पहरा है। प्रत्येक उदाहरण के लिए केवल एक धागा ब्लॉक में प्रवेश कर सकता है।

synchronized(X.class)यह सुनिश्चित करने के लिए उपयोग किया जाता है कि ब्लॉक में एक थ्रेड है। synchronized(this)यह सुनिश्चित करता है कि प्रति उदाहरण एक धागा ठीक है। यदि यह ब्लॉक कोड में वास्तविक कोड को सुरक्षित बनाता है तो कार्यान्वयन पर निर्भर करता है। यदि केवल उदाहरण की स्थिति को म्यूट करें synchronized(this)पर्याप्त है।


6
"उदाहरण के रूप में कई थ्रेड ब्लॉक में प्रवेश कर सकते हैं" उदाहरण का अर्थ है कि दूसरा रूप एक सेमाफोर के रूप में कार्य करता है जो सच नहीं है। आपको कुछ कहना चाहिए: "सिंक्रनाइज़ (यह) यह सुनिश्चित करता है कि कक्षा के दिए गए उदाहरण के लिए केवल एक धागा ब्लॉक में प्रवेश कर सकता है"।
livp

सही किया। मैंने कहा कि इरादा है।
थॉमस जुंग

2
वर्ग उदाहरण बनाम उदाहरण क्या है?
वीशी ज़ेंग

इसलिए, यदि आपके पास एक स्टैटिक तरीका है और हम उसके सभी शरीर को सिंक्रोनाइज़ नहीं करना चाहते हैं, तो हम सिंक्रोनाइज़ (यह) अच्छा नहीं है, इसके बजाय सिंक्रोनाइज़ (Foo.class) करना उचित है। क्या वह सही है?
krupal.agile

84

अन्य उत्तरों में जोड़ने के लिए:

static void myMethod() {
  synchronized(MyClass.class) {
    //code
  }
}

के बराबर है

static synchronized void myMethod() {
  //code
}

तथा

void myMethod() {
  synchronized(this) {
    //code
  }
}

के बराबर है

synchronized void myMethod() {
  //code
}

12
मुझे यह समझने में दूसरी बार लगी कि पहले दो उदाहरणों में कीवर्ड "स्टैटिक" है। बस दूसरों की ओर इशारा करते हुए जिन्होंने इसे देखा होगा और चूक गए होंगे। स्थिर कीवर्ड के बिना पहले दो उदाहरण समान नहीं होंगे।
कर्टज़बॉट

1
वे उदाहरण समकक्ष नहीं हैं! जब एक थ्रेड विधियों को कॉल करने का प्रयास करता है तो सिंक्रनाइज़ किए गए तरीके "सिंक्रनाइज़" एक छेद के रूप में होते हैं। दूसरी ओर, ब्लॉक में उनके ऊपर और नीचे कोड हो सकते हैं, जो कई थ्रेड से निष्पादित हो सकते हैं। वे केवल ब्लॉक के भीतर सिंक्रनाइज़ करते हैं! यह वही नहीं है!
जैकसन एफ 1re

सार्वजनिक स्थैतिक सिंगलटन getInstance () {if (उदाहरण == null) {सिंक्रोनाइज़ (Singleton.class) {उदाहरण = नया सिंगलटन (); }} वापसी उदाहरण; }
JacksOnF1re

2
पूरे मुद्दे वहाँ वह यह है कि है बाहर कोई कोड synchronizedब्लॉक। जो उन्हें समकक्ष बनाता है। यदि आप एक उदाहरण बदलते हैं, तो वे वास्तव में समान नहीं हैं।
जोर्न

23

नहीं, पहले के वर्ग परिभाषा पर एक ताला मिलेगा MyClass, इसके सभी उदाहरण नहीं। हालांकि, अगर एक उदाहरण में उपयोग किया जाता है, तो यह प्रभावी रूप से अन्य सभी उदाहरणों को अवरुद्ध करेगा, क्योंकि वे एक एकल वर्ग परिभाषा साझा करते हैं।

दूसरे को केवल वर्तमान उदाहरण पर लॉक मिलेगा।

जैसे कि क्या यह आपकी वस्तुओं को सुरक्षित बनाता है, यह कहीं अधिक जटिल प्रश्न है - हमें आपका कोड देखना होगा!


1
हां, MyClass.class का कोई भी स्थिर वैरिएबल हो सकता है और इसका समान प्रभाव हो सकता है।
पैंसेंटन

0

हाँ, यह (किसी भी सिंक्रनाइज़ किए गए ब्लॉक / फ़ंक्शन पर) होगा।

मैं खुद के लिए कुछ दिनों के लिए इस सवाल के बारे में सोच रहा था (वास्तव में कोटलिन में)। मुझे अंत में अच्छी व्याख्या मिली और मैं इसे साझा करना चाहता हूं:

क्लास लेवल लॉक रनटाइम पर क्लास के सभी उपलब्ध इंस्टेंस में से किसी एक में सिंक्रोनाइज़्ड ब्लॉक में एंटर करने के लिए कई थ्रेड्स को रोकता है। इसका मतलब है कि अगर रनटाइम में डेमोक्लास के 100 इंस्टेंसेस हैं, तो एक समय में किसी भी एक में केवल एक धागा ही डेमोमेथोड () को निष्पादित कर पाएगा और अन्य सभी इंस्टेंस अन्य थ्रेड्स के लिए लॉक हो जाएंगे।

स्थिर डेटा थ्रेड को सुरक्षित बनाने के लिए हमेशा क्लास स्तर की लॉकिंग की जानी चाहिए। जैसा कि हम जानते हैं कि स्टेटिक कीवर्ड क्लास स्तर के तरीकों का डेटा संबद्ध करता है, इसलिए स्टैटिक फ़ील्ड्स या लॉकिंग क्लास स्तर पर इसे बनाने के लिए लॉकिंग का उपयोग करें।

प्लस । नोटिस करने के लिए क्यों .class यह सिर्फ इसलिए .classहै क्योंकि वर्ग के किसी भी स्थिर चर के समान है:

private final static Object lock = new Object();

जहाँ लॉक वैरिएबल का नाम क्लास है और टाइप क्लास <T> है

और पढ़ें: https://howtodoinjava.com/java/multi-threading/object-vs-class-level-locking/

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.