जवाबों:
जब बूलियन की जांच और बदलने के लिए कई थ्रेड्स की आवश्यकता होती है। उदाहरण के लिए:
if (!initialized) {
initialize();
initialized = true;
}
यह धागा-सुरक्षित नहीं है। आप इसका उपयोग करके इसे ठीक कर सकते हैं AtomicBoolean:
if (atomicInitialized.compareAndSet(false, true)) {
initialize();
}
trueजब initialize()पूरा नहीं हुआ है तो अन्य धागा देख सकते हैं । इसलिए, यह केवल तभी काम करता है जब अन्य सूत्र पूरा होने की परवाह नहीं करते हैं initialize()।
initializedइसका उपयोग केवल यह सुनिश्चित करने के लिए किया जा रहा है कि एक और केवल एक धागा initialize()विधि को लागू करेगा । स्पष्ट रूप initializedसे सच होने का यह अर्थ नहीं है कि इस मामले में आरंभीकरण निश्चित रूप से पूरा हो गया है, इसलिए शायद थोड़ा अलग शब्द यहां बेहतर होगा। फिर, यह इस बात पर निर्भर करता है कि इसका उपयोग किस लिए किया जा रहा है।
volatile booleanरूप में ही नहीं होगा AtomicBoolean?
synchronizedब्लॉक का उपयोग करना है, जिस स्थिति में आपको अब AtomicBooleanए की जरूरत नहीं है , बस ए volatile boolean। ( if(! this.initialized) { synchronized(this) { if(! this.initialized) { initialize(); this.initialized = true; } } }यह सुनिश्चित करेगा कि केवल एक थ्रेड कॉल initialize, और यह कि अन्य सभी धागे इसके लिए प्रतीक्षा करते हैं, बशर्ते कि initializedचिह्नित किया गया हो volatile।)
यहाँ नोट्स ( ब्रायन गोएट्ज़ पुस्तक से ) मैंने बनाया है, जो आपकी मदद कर सकता है
AtomicXXX की कक्षाएं
गैर-अवरोधक तुलना-और-स्वैप कार्यान्वयन प्रदान करें
हार्डवेयर द्वारा प्रदान किए गए समर्थन का लाभ उठाता है (इंटेल पर CMPXCHG निर्देश) जब आपके थ्रू बहुत सारे थ्रेड्स इन परमाणु समवर्ती API का उपयोग करते हैं, तो वे उस कोड की तुलना में बहुत बेहतर होंगे जो ऑब्जेक्ट स्तर पर नज़र रखता / सिंक्रनाइज़ेशन का उपयोग करता है। चूंकि, Java के सिंक्रोनाइज़ेशन मैकेनिज़्म कोड को प्रतीक्षा करते हैं, जब आपके महत्वपूर्ण अनुभागों के माध्यम से बहुत सारे थ्रेड चल रहे होते हैं, तो सिंक्रोनाइज़ेशन मैकेनिज़्म को प्रबंधित करने के लिए CPU की पर्याप्त मात्रा स्वयं खर्च होती है (प्रतीक्षा, सूचित करना, आदि)। चूंकि नया एपीआई हार्डवेयर स्तर के निर्माण (परमाणु चर) का उपयोग करता है और थ्रेड-सुरक्षा को लागू करने के लिए प्रतीक्षा और लॉक फ्री एल्गोरिदम का उपयोग करता है, इसलिए सीपीयू का बहुत अधिक समय सिंक्रनाइज़ेशन के प्रबंधन के बजाय "सामान करने" में खर्च होता है।
न केवल बेहतर थ्रूपुट की पेशकश करते हैं, बल्कि वे गतिरोध और प्राथमिकता के उलट के रूप में लाइनिंग की समस्याओं के लिए अधिक प्रतिरोध प्रदान करते हैं।
दो मुख्य कारण हैं कि आप एक परमाणु बूलियन का उपयोग क्यों कर सकते हैं। पहले इसकी उत्परिवर्तन, आप इसे एक संदर्भ के रूप में पारित कर सकते हैं और मूल्य बदल सकते हैं जो बूलियन से जुड़ा हुआ है, उदाहरण के लिए।
public final class MyThreadSafeClass{
private AtomicBoolean myBoolean = new AtomicBoolean(false);
private SomeThreadSafeObject someObject = new SomeThreadSafeObject();
public boolean doSomething(){
someObject.doSomeWork(myBoolean);
return myBoolean.get(); //will return true
}
}
और someObject क्लास में
public final class SomeThreadSafeObject{
public void doSomeWork(AtomicBoolean b){
b.set(true);
}
}
इससे भी महत्वपूर्ण बात यह है कि इसका धागा सुरक्षित है और डेवलपर्स को वर्ग बनाए रखने का संकेत दे सकता है, कि इस चर को संशोधित किया जा सकता है और कई थ्रेड्स से पढ़ा जा सकता है। यदि आप एक AtomicBoolean का उपयोग नहीं करते हैं, तो आपको अपने द्वारा उपयोग किए गए बूलियन वैरिएबल को सिंक्रनाइज़ करना चाहिए और इसे क्षेत्र के पढ़ने और लिखने के आसपास अस्थिर या सिंक्रनाइज़ करके घोषित करना चाहिए।
AtomicBooleanवर्ग आप एक बूलियन मान कि आप atomically अद्यतन कर सकते हैं देता है। बूलियन वैरिएबल तक पहुंचने वाले कई थ्रेड्स का उपयोग करने पर इसका उपयोग करें।
Java.util.concurrent.atomic पैकेज सिंहावलोकन तुम क्या इस पैकेज में कक्षाएं करते हैं और जब उन्हें इस्तेमाल करने का एक अच्छा उच्च स्तरीय विवरण देता है। मैं ब्रायन गोएत्ज़ की पुस्तक जावा कॉन्सेप्टरी इन प्रैक्टिस भी सुझाऊँगा ।
पैकेज विवरण से अंश
पैकेज java.util.concurrent.atomic विवरण: कक्षाओं का एक छोटा टूलकिट जो एकल चर पर लॉक-फ्री थ्रेड-सुरक्षित प्रोग्रामिंग का समर्थन करता है। [...]
इन विधियों के विनिर्देशन कुशल मशीन-स्तरीय परमाणु निर्देशों को लागू करने में सक्षम बनाते हैं जो समकालीन प्रोसेसर पर उपलब्ध हैं। [...]
कक्षाओं के उदाहरण AtomicBoolean, AtomicInteger, AtomicLong, और AtomicReference प्रत्येक संबंधित प्रकार के एकल चर तक पहुंच और अद्यतन प्रदान करते हैं। [...]
परमाणुओं के अभिगम और अद्यतन के लिए स्मृति प्रभाव आम तौर पर वाष्पशील के नियमों का पालन करते हैं:
- एक अस्थिर चर को पढ़ने के स्मृति प्रभाव प्राप्त होते हैं।
- सेट में वाष्पशील चर लिखने (असाइन करने) का मेमोरी इफेक्ट होता है।
- कमजोरकंपनीएंडसेट एटोमिकली पढ़ता है और सशर्त रूप से एक चर लिखता है, उस चर पर अन्य मेमोरी ऑपरेशन के संबंध में आदेश दिया जाता है, लेकिन अन्यथा एक साधारण गैर-वाष्पशील मेमोरी ऑपरेशन के रूप में कार्य करता है।
- ComparAndSet और अन्य सभी रीड-एंड-अपडेट ऑपरेशन जैसे getAndIncrement में वाष्पशील चर को पढ़ने और लिखने दोनों की स्मृति प्रभाव होता है।
volatile booleanबनामAtomicBoolean: stackoverflow.com/questions/3786825/…