आप एक विशिष्ट वस्तु पर सिंक्रनाइज़ या तो कुछ नामित स्थिर ताला वस्तु, या वर्ग वस्तु (जो जब स्थिर तरीकों सिंक्रनाइज़ किए जाने की घोषणा की जाती है होता है):
class X {
private static final Object lock = new Object();
public void oneAtATime() {
synchronized (lock) {
// Do stuff
}
}
}
class Y {
public void oneAtATime() {
synchronized (Y.class) {
// Do stuff
}
}
}
प्रत्येक संस्करण का अपना पक्ष-विपक्ष है ; कक्षा पर लॉकिंग, कोड के बाहर, अन्य कोडों को अपने स्वयं के कारणों के लिए उसी लॉक का उपयोग करने की अनुमति देता है (जो इसे आपके द्वारा प्रदान की जाने वाली तुलना में अधिक उच्च स्तरीय सिंक्रनाइज़ेशन को ऑर्केस्ट्रेट करने की अनुमति देता है) जबकि static final Object lock
दृष्टिकोण आपको लॉक करके इसे प्रतिबंधित करने देता है फ़ील्ड प्राइवेट (जो लॉकिंग के बारे में कारण बनाना आसान बनाता है और आपके कोड को डेडलॉकिंग से बचता है क्योंकि किसी और ने खराब कोड लिखा है)।
आप निश्चित रूप से भी कुछ तुल्यकालन तंत्र java.util.concurrent
से, स्पष्ट Lock
रों है, जो ताला लगा (और ReentrantLock
वर्तमान में एक छोटे से उच्च विवाद के तहत निहित ताले तुलना में बेहतर प्रदर्शन) पर अधिक नियंत्रण प्रदान करते हैं की तरह इस्तेमाल कर सकते हैं।
संपादित करें: ध्यान दें कि स्थिर/वैश्विक ताले जाने के लिए एक शानदार तरीका नहीं हैं - यह वर्ग कभी भी बनाए अनिवार्य रूप से हर दूसरे उदाहरण से संबद्ध रहेगा के प्रत्येक उदाहरण (जो, एक तरफ यह करने से मतलब है कोड का परीक्षण या पढ़ने के लिए कठिन, स्केलेबिलिटी को गंभीर रूप से नुकसान पहुंचा सकता है)। मुझे लगता है कि आप किसी प्रकार की वैश्विक स्थिति को सिंक्रनाइज़ करने के लिए ऐसा करते हैं? उस स्थिति में, मैं उस वर्ग में वैश्विक/स्थैतिक राज्य को लपेटने पर विचार करता हूं, और वैश्विक स्तर पर प्रति-सिंक्रनाइज़ेशन प्रति-उदाहरण लागू करता हूं।
कुछ इस तरह के बजाय
:
class Z {
private static int state;
public void oneAtATime(){
synchronized (Z.class) {
state++;
}
}
}
इस तरह करें:
class State {
private int value;
public synchronized void mutate(){ value++; }
}
class Z {
private final State state;
public Z(State state){
this.state = state;
}
public void oneAtATime(){
state.mutate();
}
}
// Usage:
State s1 = new State(), s2 = new State();
Z foo = new Z(s1);
Z bar = new Z(s1);
Z frob = new Z(s2);
Z quux = new Z(s2);
अब foo
और bar
अभी भी एक दूसरे से जुड़े होते हैं, लेकिन वे स्वतंत्र रूप से frob
और quux
से काम कर सकते हैं।
क्या आप समझा सकते हैं कि आपको ऐसा करने की आवश्यकता क्यों है? मुझे एहसास है कि आप गलत समस्या पर हमला कर सकते हैं। विधि कॉल को सिंक्रनाइज़ करने की आवश्यकता * आपके वर्ग के पूरी तरह से अलग उदाहरण * वास्तविक समस्या की तरह लगता है कहीं और है। –