जावा अस्थिर संदर्भ बनाम परमाणु संदर्भ


135

वहाँ एक के बीच कोई अंतर है volatileऑब्जेक्ट संदर्भ और AtomicReferenceमामले मैं सिर्फ का प्रयोग करेंगे में get()और set()से -methods AtomicReference?

जवाबों:


114

संक्षिप्त उत्तर है: नहीं।

से java.util.concurrent.atomicपैकेज प्रलेखन। उद्धरण के लिए:

परमाणुओं के अभिगम और अद्यतन के लिए स्मृति प्रभाव आम तौर पर वाष्पशील के नियमों का पालन करते हैं:

  • getएक volatileचर पढ़ने के स्मृति प्रभाव है ।
  • setकिसी volatileचर को लिखने (असाइन करने) का मेमोरी इफेक्ट होता है ।

वैसे, वह दस्तावेज बहुत अच्छा है और सब कुछ समझाया गया है।


AtomicReference::lazySetएक नया (जावा 6+) प्रचालन है जिसे वैरिएंट के माध्यम से शब्दावलियों को अस्वीकार्य किया गया volatileहै। देखें इस पोस्ट में अधिक जानकारी के लिए।


11
और लंबा जवाब होगा?
जुलिएन ग्रेनियर

माना। हमें कम से कम एक लिंक की आवश्यकता है।
जुलिएन चास्तांग

2
उत्तर देने के लिए लिंक: java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/atomic/…
एलेक्स सिमन

42

नहीं वहाँ नहीं है।

AtomicReference द्वारा प्रदान की गई अतिरिक्त शक्ति की तुलनाAndSet () विधि और मित्र है। यदि आपको उन विधियों की आवश्यकता नहीं है, तो एक वाष्पशील संदर्भ एटॉमिकरेंस.सेट () और .get () के रूप में एक ही शब्दार्थ प्रदान करता है।


14

कई अंतर और व्यापार हैं:

  1. गेट AtomicReference/ सेट के उपयोग से एक ही जेएमएम शब्दार्थ एक अस्थिर क्षेत्र (जेवाडॉक राज्यों के रूप में) के रूप में है, लेकिन AtomicReferenceएक संदर्भ के चारों ओर एक आवरण है, इसलिए क्षेत्र में किसी भी एक्सेस में एक और पॉइंटर चेस शामिल है

  2. स्मृति पदचिह्न गुणा किया जाता है (एक संकुचित उफ़ वातावरण है, जो सबसे VMs के लिए सच है यह सोचते हैं):

    • वाष्पशील रेफ = 4 बी
    • AtomicReference = 4 बी + 16 बी (12 बी ऑब्जेक्ट हेडर + 4 बी रिफ फील्ड)
  3. AtomicReferenceएक अस्थिर संदर्भ की तुलना में एक अमीर एपीआई प्रदान करता है। आप एक AtomicFieldUpdaterजावा का उपयोग करके या जावा 9 ए के साथ अस्थिर संदर्भ के लिए एपीआई प्राप्त कर सकते हैं VarHandlesun.misc.Unsafeयदि आप कैंची से दौड़ना पसंद करते हैं तो आप सीधे पहुंच सकते हैं । AtomicReferenceका उपयोग कर ही लागू किया जाता है Unsafe

तो, जब एक दूसरे को चुनना अच्छा होता है:

  • केवल जरूरत है / सेट? एक वाष्पशील क्षेत्र, सबसे सरल समाधान और सबसे कम ओवरहेड के साथ छड़ी।
  • अतिरिक्त कार्यक्षमता की आवश्यकता है? यदि यह आपके कोड का एक प्रदर्शन (गति / मेमोरी ओवरहेड) है, तो संवेदनशील AtomicReference/ AtomicFieldUpdater/ Unsafeजहां आप अपने प्रदर्शन लाभ के लिए पठनीयता और जोखिम में भुगतान करते हैं, के बीच चयन करते हैं। यदि यह एक संवेदनशील क्षेत्र नहीं है तो बस जाएं AtomicReference। लाइब्रेरी लेखक आमतौर पर लक्षित JDKs, अपेक्षित API प्रतिबंधों, मेमोरी बाधाओं और इसी तरह के आधार पर इन विधियों के मिश्रण का उपयोग करते हैं।

7

JDK स्रोत कोड इस तरह के भ्रमों का जवाब देने के सर्वोत्तम तरीकों में से एक है। यदि आप AtomicReference में कोड को देखते हैं, तो यह ऑब्जेक्ट भंडारण के लिए एक अस्थिर चर का उपयोग करता है।

private volatile V value;

तो, जाहिर है कि अगर आप परमाणुकरण पर सिर्फ गेट () और सेट () का उपयोग करने जा रहे हैं तो यह एक अस्थिर चर का उपयोग करने जैसा है। लेकिन जैसा कि अन्य पाठकों ने टिप्पणी की है, एटॉमिक रीफरेंस अतिरिक्त सीएएस शब्दार्थ प्रदान करता है। इसलिए, पहले यह तय करें कि आप कैस शब्दार्थ चाहते हैं या नहीं, और यदि आप केवल परमाणु ऊर्जा का उपयोग करते हैं।


13
"JDK स्रोत कोड इस तरह के भ्रमों का जवाब देने के सर्वोत्तम तरीकों में से एक है" => मैं जरूरी सहमत नहीं हूं - javadoc (जो वर्ग का अनुबंध है) सबसे अच्छा तरीका है। आप कोड में जो पाते हैं वह विशिष्ट कार्यान्वयन के लिए प्रश्न का उत्तर देता है लेकिन कोड बदल सकता है।
16

4
उदाहरण के लिए हैशमैप में चर JDK 6 में अस्थिर था, लेकिन जावा 7 में अब कोई अस्थिर नहीं है। क्या आपने इस तथ्य पर अपना कोड आधारित किया है कि चर अस्थिर था, यह तब टूट जाता था जब आपका JDK को कुचलना ... उदाहरण के लिए उदाहरण है अलग है, लेकिन आप बिंदु मिलता है।
17

क्या यह कैस कुछ मानक संक्षिप्त नाम है?
अब्बास

1
तुलना करें और स्वैप करें =)
अंतहीन

4

AtomicReferenceअतिरिक्त कार्यक्षमता प्रदान करता है जो एक सादा अस्थिर चर प्रदान नहीं करता है। जैसा कि आपने एपीआई जावदॉक को पढ़ा है, आपको यह पता होगा, लेकिन यह एक लॉक भी प्रदान करता है जो कुछ कार्यों के लिए उपयोगी हो सकता है।

हालाँकि, जब तक आपको इस अतिरिक्त कार्यक्षमता की आवश्यकता नहीं होती है, मेरा सुझाव है कि आप सादे का उपयोग करें volatile क्षेत्र का ।


तो, अंतर, उनके प्रदर्शन में है। यदि कोई अंतर नहीं था, तो आप कभी भी एक दूसरे पर प्रयोग करने का सुझाव नहीं देंगे।
बीटी

प्रदर्शन बहुत अधिक है। एक AtomicRefrence जटिलता और स्मृति उपयोग जोड़ता है।
पीटर लॉरी

@ बीटी ए volatile क्षेत्र को किसी भी नियमित क्षेत्र की तरह इस्तेमाल किया जा सकता है, जबकि AtomicReferenceआवश्यकता होती है मूल्य को एक्सेस करने के तरीकों getऔर setतरीकों से।
डेविड हार्कनेस

0

कभी-कभी अगर आप केवल उपयोग और सेट करते हैं, तो भी 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;

हालाँकि, दूसरे को "कोड सफाई" के दौरान भविष्य में गलती से किसी के द्वारा हटाए जाने की अधिक संभावना है।

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