जवाबों:
चूंकि किसी स्थिर विधि में कोई संबद्ध ऑब्जेक्ट नहीं है, तो क्या ऑब्जेक्ट के बजाय क्लास पर सिंक्रनाइज़ कीवर्ड लॉक होगा?
हाँ। :)
this
उदाहरण के तरीकों पर अधिग्रहित ताला है- , कृपया इसे ऑस्कर ठीक करें।
ऑस्कर के लिए थोड़ा विस्तार से जोड़ने के लिए (सुखदायक रसीला!) उत्तर, जावा भाषा विशिष्टता पर संबंधित अनुभाग 8.4.3.6, 'सिंक्रोनाइज़्ड मेथड्स' है :
निष्पादित होने से पहले एक समन्वित विधि एक मॉनिटर ( .17.1 ) प्राप्त करती है । एक वर्ग (स्थिर) विधि के लिए, विधि के वर्ग के लिए क्लास ऑब्जेक्ट से जुड़े मॉनिटर का उपयोग किया जाता है। एक उदाहरण विधि के लिए, इस के साथ जुड़े मॉनिटर (जिस वस्तु के लिए विधि लागू की गई थी) का उपयोग किया जाता है।
एक बिंदु पर आपको सावधान रहना होगा (कई प्रोग्रामर आम तौर पर उस जाल में पड़ जाते हैं) यह है कि सिंक्रनाइज़ स्थिर विधियों और सिंक गैर-स्थिर तरीकों के बीच कोई लिंक नहीं है, अर्थात:
class A {
static synchronized f() {...}
synchronized g() {...}
}
मुख्य:
A a = new A();
धागा 1:
A.f();
धागा 2:
a.g();
एफ () और जी () एक दूसरे के साथ सिंक्रनाइज़ नहीं हैं और इस तरह पूरी तरह से समवर्ती निष्पादित कर सकते हैं।
synchronized (MyClass.class) {...}
।
जब तक आप जी लागू नहीं करते हैं () निम्नानुसार है:
g() {
synchronized(getClass()) {
...
}
}
मुझे यह पैटर्न तब भी उपयोगी लगता है जब मैं वस्तु के विभिन्न उदाहरणों के बीच आपसी बहिष्करण को लागू करना चाहता हूं (जो कि जब किसी बाहरी संसाधन के उदाहरण के लिए आवश्यक होता है)।
getClass()
रिटर्न क्रम प्रकार; यदि आप कक्षा को उपवर्गित करते हैं, तो अभिभावक वर्ग और बालक वर्ग अलग-अलग तालों पर सिंक्रनाइज़ हो जाएंगे। synchronized(MyClass.class)
जाने के लिए रास्ता है अगर आपको यह सुनिश्चित करने की आवश्यकता है कि सभी उदाहरण एक ही लॉक का उपयोग करें।
आंतरिक ताले और तुल्यकालन पर oracle प्रलेखन पृष्ठ पर एक नज़र है
आपको आश्चर्य हो सकता है कि जब एक स्थिर सिंक्रनाइज़ेशन विधि लागू होती है, तब क्या होता है, क्योंकि एक स्थिर विधि एक वर्ग से जुड़ी होती है, वस्तु नहीं। इस मामले में, धागा क्लास से जुड़ी क्लास ऑब्जेक्ट के लिए आंतरिक लॉक का अधिग्रहण करता है । इस प्रकार वर्ग के स्थैतिक क्षेत्रों तक पहुंच को एक लॉक द्वारा नियंत्रित किया जाता है जो कक्षा के किसी भी उदाहरण के लिए लॉक से अलग होता है ।
एक स्थैतिक विधि में एक संबद्ध वस्तु भी होती है। यह JDK टूलकिट में Class.class फ़ाइल के अंतर्गत आता है। जब .class फ़ाइल RAM में लोड होती है, तो Class.class इसका एक उदाहरण बनाता है जिसे टेम्पलेट ऑब्जेक्ट कहा जाता है।
जैसे: - जब आप मौजूदा ग्राहक वर्ग से ऑब्जेक्ट बनाने की कोशिश करते हैं जैसे
Customer c = new Customer();
Customer.class RAM में लोड होता है। उस पल में JDK टूलकिट में Class.class, टेम्पलेट ऑब्जेक्ट नामक एक ऑब्जेक्ट बनाता है और उस टेम्पलेट ऑब्जेक्ट में Customer.class लोड करता है। उस Customer.class के सदस्य उस टेम्पलेट ऑब्जेक्ट में विशेषताएँ और विधियाँ बन जाते हैं।
तो एक स्थिर विधि या विशेषता में भी एक वस्तु है
नीचे दिए गए उदाहरण क्लास और ऑब्जेक्ट लॉक के बीच अधिक स्पष्टता प्रदान करते हैं, आशा है कि नीचे दिए गए उदाहरण दूसरों को भी मदद करेंगे :)
उदाहरण के लिए हमारे पास निम्न विधियाँ हैं एक वर्ग को प्राप्त करने और दूसरी वस्तु को प्राप्त करने के लिए ताला:
public class MultiThread {
public static synchronized void staticLock() throws InterruptedException {
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
public synchronized void objLock() throws InterruptedException {
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
तो, अब हम निम्नलिखित परिदृश्य हो सकते हैं:
जब एक ही वस्तु का उपयोग करने वाले धागे एक ही समय objLock
या staticLock
विधि तक पहुंचने की कोशिश करते हैं (यानी दोनों धागे एक ही विधि का उपयोग करने की कोशिश कर रहे हैं)
Thread-0 0
Thread-0 1
Thread-0 2
Thread-0 3
Thread-0 4
Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 3
Thread-1 4
का उपयोग करते हुए धागे जब एक ही वस्तु का उपयोग करने की कोशिश करता staticLock
है और objLock
पद्धतियां ठीक उसी समय (कोशिश करता विभिन्न तरीकों एक्सेस करने वाले)
Thread-0 0
Thread-1 0
Thread-0 1
Thread-1 1
Thread-0 2
Thread-1 2
Thread-1 3
Thread-0 3
Thread-0 4
Thread-1 4
जब अलग-अलग ऑब्जेक्ट का उपयोग करके थ्रेड्स पहुंच staticLock
विधि का उपयोग करता है
Thread-0 0
Thread-0 1
Thread-0 2
Thread-0 3
Thread-0 4
Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 3
Thread-1 4
जब अलग-अलग ऑब्जेक्ट का उपयोग करके थ्रेड्स पहुंच objLock
विधि का उपयोग करता है
Thread-0 0
Thread-1 0
Thread-0 1
Thread-1 1
Thread-0 2
Thread-1 2
Thread-1 3
Thread-0 3
Thread-0 4
Thread-1 4
उन लोगों के लिए जो स्टैंग क्लास के लिए क्लास स्टिग्ग जैसे लॉक्ड स्टैटिक सिंक्रोनाइज़्ड मेथड नहीं हैं, उदाहरण के लिए, जबकि जावा में "इस" कीवर्ड द्वारा दर्शाए गए ऑब्जेक्ट के वर्तमान इंस्टेंस पर सिंक्रोनाइज़्ड मेथड लॉक्स। चूंकि ये दोनों ऑब्जेक्ट अलग-अलग हैं, इसलिए उनके पास अलग-अलग लॉक हैं, जबकि एक थ्रेड स्टैटिक सिंक्रोनाइज़्ड मेथड को अंजाम दे रहा है, जावा में दूसरे थ्रेड को उस थ्रेड के लौटने की प्रतीक्षा करने की आवश्यकता नहीं है, बल्कि यह अलग-अलग लॉक बाइटेड .class शाब्दिक और लॉक में प्रवेश करेगा। स्थिर सिंक्रनाइज़ विधि।