जवाबों:
संक्षिप्त उत्तर है: नहीं।
से java.util.concurrent.atomicपैकेज प्रलेखन। उद्धरण के लिए:
परमाणुओं के अभिगम और अद्यतन के लिए स्मृति प्रभाव आम तौर पर वाष्पशील के नियमों का पालन करते हैं:
getएकvolatileचर पढ़ने के स्मृति प्रभाव है ।setकिसीvolatileचर को लिखने (असाइन करने) का मेमोरी इफेक्ट होता है ।
वैसे, वह दस्तावेज बहुत अच्छा है और सब कुछ समझाया गया है।
AtomicReference::lazySetएक नया (जावा 6+) प्रचालन है जिसे वैरिएंट के माध्यम से शब्दावलियों को अस्वीकार्य किया गया volatileहै। देखें इस पोस्ट में अधिक जानकारी के लिए।
कई अंतर और व्यापार हैं:
गेट AtomicReference/ सेट के उपयोग से एक ही जेएमएम शब्दार्थ एक अस्थिर क्षेत्र (जेवाडॉक राज्यों के रूप में) के रूप में है, लेकिन AtomicReferenceएक संदर्भ के चारों ओर एक आवरण है, इसलिए क्षेत्र में किसी भी एक्सेस में एक और पॉइंटर चेस शामिल है ।
स्मृति पदचिह्न गुणा किया जाता है (एक संकुचित उफ़ वातावरण है, जो सबसे VMs के लिए सच है यह सोचते हैं):
AtomicReference = 4 बी + 16 बी (12 बी ऑब्जेक्ट हेडर + 4 बी रिफ फील्ड)AtomicReferenceएक अस्थिर संदर्भ की तुलना में एक अमीर एपीआई प्रदान करता है। आप एक AtomicFieldUpdaterजावा का उपयोग करके या जावा 9 ए के साथ अस्थिर संदर्भ के लिए एपीआई प्राप्त कर सकते हैं VarHandle। sun.misc.Unsafeयदि आप कैंची से दौड़ना पसंद करते हैं तो आप सीधे पहुंच सकते हैं । AtomicReferenceका उपयोग कर ही लागू किया जाता है Unsafe।
तो, जब एक दूसरे को चुनना अच्छा होता है:
AtomicReference/ AtomicFieldUpdater/ Unsafeजहां आप अपने प्रदर्शन लाभ के लिए पठनीयता और जोखिम में भुगतान करते हैं, के बीच चयन करते हैं। यदि यह एक संवेदनशील क्षेत्र नहीं है तो बस जाएं AtomicReference। लाइब्रेरी लेखक आमतौर पर लक्षित JDKs, अपेक्षित API प्रतिबंधों, मेमोरी बाधाओं और इसी तरह के आधार पर इन विधियों के मिश्रण का उपयोग करते हैं।JDK स्रोत कोड इस तरह के भ्रमों का जवाब देने के सर्वोत्तम तरीकों में से एक है। यदि आप AtomicReference में कोड को देखते हैं, तो यह ऑब्जेक्ट भंडारण के लिए एक अस्थिर चर का उपयोग करता है।
private volatile V value;
तो, जाहिर है कि अगर आप परमाणुकरण पर सिर्फ गेट () और सेट () का उपयोग करने जा रहे हैं तो यह एक अस्थिर चर का उपयोग करने जैसा है। लेकिन जैसा कि अन्य पाठकों ने टिप्पणी की है, एटॉमिक रीफरेंस अतिरिक्त सीएएस शब्दार्थ प्रदान करता है। इसलिए, पहले यह तय करें कि आप कैस शब्दार्थ चाहते हैं या नहीं, और यदि आप केवल परमाणु ऊर्जा का उपयोग करते हैं।
AtomicReferenceअतिरिक्त कार्यक्षमता प्रदान करता है जो एक सादा अस्थिर चर प्रदान नहीं करता है। जैसा कि आपने एपीआई जावदॉक को पढ़ा है, आपको यह पता होगा, लेकिन यह एक लॉक भी प्रदान करता है जो कुछ कार्यों के लिए उपयोगी हो सकता है।
हालाँकि, जब तक आपको इस अतिरिक्त कार्यक्षमता की आवश्यकता नहीं होती है, मेरा सुझाव है कि आप सादे का उपयोग करें volatile क्षेत्र का ।
volatile क्षेत्र को किसी भी नियमित क्षेत्र की तरह इस्तेमाल किया जा सकता है, जबकि AtomicReferenceआवश्यकता होती है मूल्य को एक्सेस करने के तरीकों getऔर setतरीकों से।
कभी-कभी अगर आप केवल उपयोग और सेट करते हैं, तो भी AtomicReference एक अच्छा विकल्प हो सकता है:
अस्थिर के साथ उदाहरण:
private volatile Status status;
...
public setNewStatus(Status newStatus){
status = newStatus;
}
public void doSomethingConditionally() {
if(status.isOk()){
System.out.println("Status is ok: " + status); // here status might not be OK anymore because in the meantime some called setNewStatus(). setNewStatus should be synchronized
}
}
AtomicReference के साथ कार्यान्वयन आपको एक कॉपी-ऑन-राइट सिंक्रनाइज़ेशन मुफ्त में देगा।
private AtomicReference<Status> statusWrapper;
...
public void doSomethingConditionally() {
Status status = statusWrapper.get();
if(status.isOk()){
System.out.println("Status is ok: " + status); // here even if in the meantime some called setNewStatus() we're still referring to the old one
}
}
यदि आप प्रतिस्थापित करते हैं तो एक कह सकता है कि आपके पास अभी भी एक उचित प्रति हो सकती है:
Status status = statusWrapper.get();
साथ में:
Status statusCopy = status;
हालाँकि, दूसरे को "कोड सफाई" के दौरान भविष्य में गलती से किसी के द्वारा हटाए जाने की अधिक संभावना है।