2012-10-12 10 views
15

संभव डुप्लिकेट:
Java: volatile boolean vs AtomicBooleanपरमाणु चर पर अस्थिर आदिम का उपयोग करने के बीच क्या अंतर है?

जब यह उचित एक volatile आदिम (जैसे boolean, integer या long) के बजाय AtomicBoolean, AtomicInteger या AtomicLong, और उपाध्यक्ष प्रतिकूल उपयोग करने के लिए है?

+0

चूंकि किसी ने इसका उल्लेख किया है (न तो यहां और न ही डुप्लिकेट पर): डब्ल्यू/परमाणु वर्गों में आपके पास निफ्टी विधि आलसी है। अधिकांश आर्किटेक्चर पर यह मूल अस्थिर लेखन से बेहतर प्रदर्शन करता है (लेकिन इसमें समान अर्थशास्त्र नहीं है)। मूल रूप से आलसी सेट को सीपीयू लिखने वाले बफर को फ्लश करने की आवश्यकता नहीं होती है जो बहुत अच्छा है क्योंकि सीपीयू बंद होने पर उन्हें फ्लश किया जा सकता है। – bestsss

उत्तर

17

दृश्यता अर्थशास्त्र बिल्कुल वही है, स्थिति जहां परमाणु प्राइमेटिव का उपयोग करना उपयोगी होता है जब आपको अपने परमाणु तरीकों का उपयोग करने की आवश्यकता होती है।

उदाहरण के लिए:

if (volatileBoolean) { 
    volatileBoolean = !volatileBoolean; 
} 

एक बहु थ्रेडेड वातावरण चर दो पंक्तियों के बीच बदल सकता है के रूप में में मुद्दों बना सकते हैं। आप परीक्षण & काम की जरूरत है परमाणु होने के लिए, आप का उपयोग कर सकते हैं:

atomicBoolean.compareAndSet(true, false); 
+6

'volatileBoolean =! VolatileBoolean; 'केवल थ्रेडिंग समस्या हो सकती है। –

+0

@ पीटर Lawrey अच्छा बिंदु। – assylias

+1

क्योंकि बूलियन को नकारना एक दो-चरणीय ऑपरेशन है? –

12

का उपयोग करते हुए एक सादे अस्थिर सरल और अधिक कुशल है तुम सब करने के लिए सेट या मूल्य प्राप्त है चाहते हैं। (लेकिन & मान सेट करें)

यदि आप GetAndIncrement या तुलना करने के लिए अधिक संचालन चाहते हैं और एंड्रॉइड आपको AtomicXxxx कक्षाओं का उपयोग करने की आवश्यकता है।

+1

के बीच कोई भी धागा हो सकता है आपके उत्तर –

+0

पर आलसी सेट पर परमाणु आमतौर पर अस्थिर 'लिखने' (टीएसओ आर्किटेक्चर पर एएसपी) जीतता है लेकिन इसमें अलग-अलग अर्थशास्त्र होते हैं। – bestsss

+0

आलसीसेट तेज है क्योंकि यह सीपीयू पाइपलाइन को रोकता नहीं है। –

7

हमने अपने स्रोतों में volatile के उपयोग को प्रतिबंधित करना शुरू कर दिया है क्योंकि यह कोड लिखना बहुत आसान है जो हमेशा अपेक्षित काम नहीं करता है।

मेरे अनुभव में, लोग धागे के बीच मूल्य साझा करने के लिए अस्थिर जोड़ते हैं। और फिर, कोई और मूल्य को संशोधित करना शुरू कर देता है। और ज्यादातर समय, यह काम करता है। लेकिन उत्पादन में, आपको अजीब त्रुटियां मिलनी शुरू होती हैं जो ट्रैक करना वाकई मुश्किल होती हैं। काउंटर 100'000 गुना बढ़ाए जाते हैं (परीक्षण केवल उन्हें 10 गुना बढ़ाते हैं) लेकिन 99'997 पर समाप्त होते हैं। जावा 1.4 में, लंबे मूल्य वास्तव में शायद ही कभी भ्रष्ट हो सकते हैं।

दूसरी ओर, Atomic* सहायक वर्ग, केवल एक छोटा ओवरहेड लगाते हैं और वे हमेशा विज्ञापित के रूप में काम करते हैं।

तब तक जब तक आपके पास volatile का उपयोग करने के लिए बहुत अच्छा कारण (*) नहीं है, तो हमेशा Atomic* सहायक वर्ग पसंद करते हैं।

यदि आप नहीं जानते कि Atomic* सहायक कक्षाओं में प्रत्येक वर्ण वास्तव में क्या है, तो आपको वास्तव में volatile से बचना चाहिए।

*: समयपूर्व अनुकूलन कभी भी एक अच्छा कारण नहीं है।

+0

आपके उत्तर –

+0

* के लिए धन्यवाद * "कोड लिखना बहुत आसान है जो हमेशा अपेक्षित काम नहीं करता है।" * => क्या आप अधिक विशिष्ट हो सकते हैं? क्या आपका मतलब है कि लोग अस्थिर मानते हैं उदाहरण के लिए परमाणु गारंटी देता है? – assylias

+1

@assylias: मैंने अपने उत्तर में कुछ उदाहरण जोड़े। –

7

Atomic* कक्षाएं volatile उसी प्रकार के आदिम को लपेटती हैं। स्रोत से:

public class AtomicLong extends Number implements java.io.Serializable { 
    ... 
    private volatile long value; 
    ... 
    public final long get() { 
     return value; 
    } 
    ... 
    public final void set(long newValue) { 
     value = newValue; 
    } 

तो।

एक अस्थिर आदिम (उदा।बुलियन, पूर्णांक या लंबी) या AtomicBoolean, AtomicInteger के बजाय AtomicLong

सब आप कर रहे हैं हो रही है और स्थापित करने के लिए एक Atomic* तो आप के रूप में अच्छी सिर्फ एक volatile क्षेत्र के बजाय हो सकता है है।

... और इसके विपरीत? इस तरह के incrementAndGet(), compareAndSet(), और दूसरों को जो एक से अधिक परिचालन (प्राप्त/वेतन वृद्धि/सेट, परीक्षा/सेट) बिना लॉकिंग को लागू के रूप में

क्या Atomic* कक्षाएं आप फिर भी देते हैं, तरीकों कि अधिक उन्नत कार्यक्षमता प्रदान कर रहे हैं। यही कारण है कि Atomic* कक्षाएं इतनी शक्तिशाली हैं।

यह भी ध्यान रखना महत्वपूर्ण है कि volatile फ़ील्ड को Atomic* कक्षा का उपयोग करके क्षेत्र को किसी ऑब्जेक्ट दृष्टिकोण से महत्वपूर्ण साझा संसाधन को समाहित करने का एक अच्छा तरीका है। इसका अर्थ यह है कि डेवलपर्स केवल इस क्षेत्र से निपट नहीं सकते हैं कि यह संभवतया field++; या अन्य शर्तों के साथ समस्याओं को इंजेक्ट करने के लिए साझा नहीं किया जा रहा है जो दौड़ की स्थिति पेश करते हैं।

+1

आपके उत्तर के लिए धन्यवाद –

संबंधित मुद्दे