इसके बारे में महत्वपूर्ण बिंदु volatile:
- जावा में तुल्यकालन जावा कीवर्ड का उपयोग करके संभव है
synchronizedऔरvolatile और ताले।
- जावा में, हम
synchronizedपरिवर्तनशील नहीं हो सकते । synchronizedएक चर के साथ कीवर्ड का उपयोग करना अवैध है और इसके परिणामस्वरूप संकलन त्रुटि होगी। synchronizedजावा में चर का उपयोग करने के बजाय , आप जावा volatileचर का उपयोग कर सकते हैं , जो volatileमुख्य स्मृति से चर के मूल्य को पढ़ने के लिए जेवीएम थ्रेड्स को निर्देश देगा और इसे स्थानीय रूप से कैश नहीं करेगा।
- यदि एक चर को कई थ्रेड्स के बीच साझा नहीं किया जाता है, तो
volatileकीवर्ड का उपयोग करने की कोई आवश्यकता नहीं है ।
स्रोत
उदाहरण का उपयोग volatile:
public class Singleton {
private static volatile Singleton _instance; // volatile variable
public static Singleton getInstance() {
if (_instance == null) {
synchronized (Singleton.class) {
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
}
पहला अनुरोध आने पर हम आलसी रूप से उदाहरण बना रहे हैं।
अगर हम _instanceवैरिएबल नहीं बनाते हैं volatileतो थ्रेड जो बना रहा Singletonहै वह दूसरे थ्रेड से संवाद करने में सक्षम नहीं है। इसलिए यदि थ्रेड ए सिंगलटन उदाहरण का निर्माण कर रहा है और निर्माण के ठीक बाद, सीपीयू को नष्ट कर देता है आदि, अन्य सभी धागे मूल्य को देखने में सक्षम नहीं होंगे_instance शून्य रूप में नहीं और उन्हें विश्वास होगा कि यह अभी भी अशक्त है।
ऐसा क्यों होता है? क्योंकि पाठक थ्रेड्स कोई लॉकिंग नहीं कर रहे हैं और जब तक कि लेखक थ्रेड एक सिंक्रनाइज़ किए गए ब्लॉक से बाहर नहीं निकलता है, तब तक मेमोरी को सिंक्रनाइज़ नहीं किया जाएगा और _instanceमुख्य मेमोरी में वैल्यू अपडेट नहीं की जाएगी। जावा में वोलेटाइल कीवर्ड के साथ, यह जावा द्वारा ही संभाला जाता है और इस तरह के अपडेट सभी रीडर थ्रेड्स द्वारा दिखाई देंगे।
निष्कर्ष : volatileथ्रेड के बीच मेमोरी की सामग्री को संप्रेषित करने के लिए भी कीवर्ड का उपयोग किया जाता है।
बिना अस्थिर के उदाहरण का उपयोग:
public class Singleton{
private static Singleton _instance; //without volatile variable
public static Singleton getInstance(){
if(_instance == null){
synchronized(Singleton.class){
if(_instance == null) _instance = new Singleton();
}
}
return _instance;
}
ऊपर दिया गया कोड थ्रेड-सुरक्षित नहीं है। हालांकि यह एक बार फिर से सिंक्रनाइज़ किए गए ब्लॉक (प्रदर्शन कारणों के लिए) के भीतर उदाहरण के मूल्य की जांच करता है, जेआईटी कंपाइलर बायटेकोड को इस तरह से पुनर्व्यवस्थित कर सकता है कि निर्माण के पूरा होने से पहले इंस्टेंस का संदर्भ सेट हो जाता है। इसका मतलब यह है कि विधि getInstance () एक ऐसी वस्तु लौटाती है जो शायद पूरी तरह से शुरू नहीं की गई है। कोड थ्रेड को सुरक्षित बनाने के लिए, अस्थिर अस्थिर संस्करण के लिए जावा 5 के बाद से कीवर्ड वाष्पशील का उपयोग किया जा सकता है। वैरायटी के रूप में चिह्नित वेरिएबल्स केवल अन्य थ्रेड्स के लिए दिखाई देते हैं एक बार जब ऑब्जेक्ट का निर्माता पूरी तरह से अपने निष्पादन को समाप्त कर लेता है।
स्रोत

volatileजावा में उपयोग :
असफल-तेज़ पुनरावृत्तियों को आमतौरvolatile पर सूची ऑब्जेक्ट पर एक काउंटर का उपयोग करके लागू किया जाता है ।
- जब सूची को अद्यतन किया जाता है, तो काउंटर को बढ़ा दिया जाता है।
- जब एक
Iteratorबनाया जाता है, तो काउंटर का वर्तमान मूल्य अंदर एम्बेडेड होता हैIterator ऑब्जेक्ट ।
- जब एक
Iteratorऑपरेशन किया जाता है, तो विधि दो काउंटर मानों की तुलना करती है और ConcurrentModificationExceptionयदि वे अलग-अलग हैं तो फेंकता है ।
असफल-सुरक्षित पुनरावृत्तियों का कार्यान्वयन आमतौर पर हल्का होता है। वे आम तौर पर विशिष्ट सूची कार्यान्वयन के डेटा संरचनाओं के गुणों पर भरोसा करते हैं। कोई सामान्य पैटर्न नहीं है।
volatileJSR 133 में परिभाषित नए जावा मेमोरी मॉडल के साथ आई थी: जब एक थ्रेड एकvolatileवैरिएबल को पढ़ता है, तो यह न केवल अंतिम मूल्य को किसी अन्य थ्रेड द्वारा लिखे गए देखता है, बल्कि अन्य सभी वैरिएबल को भी लिखता है जोvolatileलेखन के समय उस दूसरे सूत्र में दिखाई दे रहे थे । इस उत्तर और इस संदर्भ को देखें ।