परमाणु / वाष्पशील / सिंक्रनाइज़ के बीच अंतर क्या है?


297

आंतरिक रूप से परमाणु / वाष्पशील / सिंक्रनाइज़ काम कैसे करते हैं?

निम्नलिखित कोड ब्लॉक के बीच अंतर क्या है?

कोड 1

private int counter;

public int getNextUniqueIndex() {
    return counter++; 
}

कोड 2

private AtomicInteger counter;

public int getNextUniqueIndex() {
    return counter.getAndIncrement();
}

कोड 3

private volatile int counter;

public int getNextUniqueIndex() {
    return counter++; 
}

volatileनिम्नलिखित तरीके से काम करता है ? है

volatile int i = 0;
void incIBy5() {
    i += 5;
}

के बराबर

Integer i = 5;
void incIBy5() {
    int temp;
    synchronized(i) { temp = i }
    synchronized(i) { i = temp + 5 }
}

मुझे लगता है कि दो धागे एक ही समय में एक सिंक्रनाइज़ ब्लॉक में प्रवेश नहीं कर सकते हैं ... क्या मैं सही हूं? अगर यह सच है तो atomic.incrementAndGet()बिना काम कैसे चलता है synchronized? और क्या यह धागा-सुरक्षित है?

और वाष्पशील चर / परमाणु चर को आंतरिक पढ़ने और लिखने के बीच क्या अंतर है? मैंने कुछ लेख में पढ़ा कि धागे में चर की एक स्थानीय प्रतिलिपि है - वह क्या है?


5
यह बहुत सारे प्रश्न बनाता है, कोड के साथ जो संकलन भी नहीं करता है। हो सकता है कि आपको एक अच्छी किताब पढ़नी चाहिए, जैसे कि जावा कॉनएरेबिलिटी इन प्रैक्टिस।
जेबी निज़ेट

4
@JBNizet तुम सही हो !!! मेरे पास वह पुस्तक है, उसमें संक्षिप्त में परमाणु अवधारणा नहीं है और मुझे उस की कुछ अवधारणाएँ नहीं मिल रही हैं। अभिशाप की यह मेरी गलती है लेखक की नहीं।
हार्डिक

4
आपको वास्तव में परवाह नहीं है कि यह कैसे लागू किया गया है (और यह ओएस के साथ बदलता रहता है)। आपको जो समझना है वह अनुबंध है: मूल्य को परमाणु रूप से बढ़ाया जाता है, और अन्य सभी धागे नए मूल्य को देखने की गारंटी देते हैं।
जेबी निज़ेट

जवाबों:


392

आप विशेष रूप से पूछ रहे हैं कि वे आंतरिक रूप से कैसे काम करते हैं , इसलिए यहां आप हैं:

कोई सिंक्रनाइज़ेशन नहीं

private int counter;

public int getNextUniqueIndex() {
  return counter++; 
}

यह मूल रूप से मेमोरी से मूल्य पढ़ता है, इसे बढ़ाता है और मेमोरी में वापस डालता है। यह सिंगल थ्रेड में काम करता है, लेकिन आजकल मल्टी-कोर, मल्टी-सीपीयू, मल्टी-लेवल कैश के युग में यह सही ढंग से काम नहीं करेगा। सबसे पहले यह दौड़ की स्थिति का परिचय देता है (कई धागे एक ही समय में मूल्य पढ़ सकते हैं), लेकिन दृश्यता की समस्याएं भी। मान केवल " स्थानीय " सीपीयू मेमोरी (कुछ कैश) में संग्रहीत किया जा सकता है और अन्य सीपीयू / कोर (और इस प्रकार - थ्रेड्स) के लिए दृश्यमान नहीं हो सकता है। यही कारण है कि कई एक धागे में एक चर की स्थानीय प्रतिलिपि को संदर्भित करते हैं । यह बहुत असुरक्षित है। इस लोकप्रिय लेकिन टूटे धागे को रोकने वाले कोड पर विचार करें:

private boolean stopped;

public void run() {
    while(!stopped) {
        //do some work
    }
}

public void pleaseStop() {
    stopped = true;
}

जोड़े volatileको stoppedचर और यह ठीक काम करता है - किसी भी अन्य धागा संशोधित करता है, तो stoppedके माध्यम से चर pleaseStop()विधि, यदि आप यह बदलाव तुरंत देखने के लिए धागा के काम करने में गारंटी दी जाती है while(!stopped)पाश। BTW यह एक धागे को बाधित करने का एक अच्छा तरीका नहीं है, यह देखें: एक धागे को कैसे रोकें जो बिना किसी उपयोग के हमेशा के लिए चल रहा है और एक विशिष्ट जावा धागे को रोक रहा है

AtomicInteger

private AtomicInteger counter = new AtomicInteger();

public int getNextUniqueIndex() {
  return counter.getAndIncrement();
}

AtomicIntegerवर्ग का उपयोग करता है कैस ( तुलना और स्वैप ) निम्न स्तर सीपीयू आपरेशन (कोई तुल्यकालन की जरूरत!) वे आप एक विशेष चर संशोधित करने के लिए केवल तभी वर्तमान मूल्य कुछ और के बराबर है (और सफलतापूर्वक लौटा दिया जाता है) की अनुमति है। इसलिए जब आप निष्पादित करते हैं तो getAndIncrement()यह वास्तव में एक लूप में चलता है (सरलीकृत वास्तविक कार्यान्वयन):

int current;
do {
  current = get();
} while(!compareAndSet(current, current + 1));

तो मूल रूप से: पढ़ा; बढ़े हुए मूल्य को संग्रहीत करने का प्रयास करें; यदि सफल नहीं है (मान अब नहीं के बराबर है current), फिर से पढ़ें और प्रयास करें। compareAndSet()मूल कोड (विधानसभा) में कार्यान्वित किया जाता है।

volatile तुल्यकालन के बिना

private volatile int counter;

public int getNextUniqueIndex() {
  return counter++; 
}

यह कोड सही नहीं है। यह दृश्यता समस्या को ठीक करता है ( volatileयह सुनिश्चित करता है कि अन्य थ्रेड्स किए गए परिवर्तन देख सकते हैं counter) लेकिन फिर भी एक दौड़ की स्थिति है। यह कई बार समझाया गया है : पूर्व / पश्चात वृद्धि परमाणु नहीं है।

इसका एकमात्र साइड इफेक्ट volatile" फ्लशिंग " कैश है, ताकि अन्य सभी पार्टियां डेटा का सबसे ताज़ा संस्करण देखें। यह ज्यादातर स्थितियों में बहुत सख्त है; यही कारण volatileहै कि डिफ़ॉल्ट नहीं है।

volatile तुल्यकालन के बिना (2)

volatile int i = 0;
void incIBy5() {
  i += 5;
}

ऊपर के रूप में एक ही समस्या है, लेकिन और भी बदतर है क्योंकि iनहीं है private। दौड़ की स्थिति अभी भी मौजूद है। यह एक समस्या क्यों है? यदि कहते हैं, दो धागे एक साथ इस कोड को चलाते हैं, तो आउटपुट + 5या हो सकता है + 10। हालाँकि, आपको परिवर्तन देखने की गारंटी है।

एकाधिक स्वतंत्र synchronized

void incIBy5() {
  int temp;
  synchronized(i) { temp = i }
  synchronized(i) { i = temp + 5 }
}

आश्चर्य, यह कोड गलत भी है। वास्तव में, यह पूरी तरह से गलत है। सबसे पहले आप उस पर सिंक्रोनाइज़ कर रहे हैं i, जो बदलने वाला है (इसके अलावा, iएक आदिम है, इसलिए मुझे लगता है कि आप Integerऑटोबॉक्सिंग के माध्यम से बनाए गए एक अस्थायी पर सिंक्रनाइज़ कर रहे हैं ...) पूरी तरह से त्रुटिपूर्ण है। आप यह भी लिख सकते हैं:

synchronized(new Object()) {
  //thread-safe, SRSLy?
}

कोई भी दो धागे एक ही लॉक से एक ही synchronizedब्लॉक में प्रवेश नहीं कर सकते हैं । इस मामले में (और इसी तरह आपके कोड में) हर निष्पादन पर लॉक ऑब्जेक्ट बदल जाता है, इसलिए प्रभावी रूप से कोई प्रभाव नहीं पड़ता है।synchronized

भले ही आपने thisसिंक्रनाइज़ेशन के लिए अंतिम चर (या ) का उपयोग किया हो , कोड अभी भी गलत है। दो धागे पहले पढ़ सकते हैं iकरने के लिए tempतुल्यकालिक (स्थानीय स्तर पर एक ही मूल्य होने tempके लिए है, तो पहले प्रदान करती है एक नया मान) i(जैसे कि, 1 से 6 तक) और अन्य एक ही बात (1 से 6 तक) करता है।

मान निर्दिष्ट करने के लिए पढ़ने से सिंक्रनाइज़ेशन को पूरा करना होगा। आपके पहले सिंक्रोनाइज़ेशन का कोई प्रभाव नहीं है (पढ़ना एक intपरमाणु है) और दूसरा भी। मेरी राय में, ये सही रूप हैं:

void synchronized incIBy5() {
  i += 5 
}

void incIBy5() {
  synchronized(this) {
    i += 5 
  }
}

void incIBy5() {
  synchronized(this) {
    int temp = i;
    i = temp + 5;
  }
}

10
केवल एक चीज मैं जोड़ूंगा कि जेवीएम उन पर काम करने के लिए रजिस्टरों में परिवर्तनशील मूल्यों को कॉपी करता है। इसका मतलब है कि एक एकल सीपीयू / कोर पर चलने वाले धागे अभी भी एक गैर-वाष्पशील चर के लिए अलग-अलग मान देख सकते हैं।
डेविड हार्कस

@thomasz: तुलनाअनसेट (वर्तमान, वर्तमान + 1) सिंक्रनाइज़ है ?? अगर दो धागे एक ही समय में इस विधि को अंजाम दे रहे हैं तो क्या होगा ??
हार्डिक

@ हार्दिक: compareAndSetकैस ऑपरेशन के आसपास सिर्फ एक पतला रैपर है। मैं अपने उत्तर में कुछ विवरणों में जाता हूं।
टॉमाज़ नर्कविक्ज़

1
@thomsasz: ठीक है, मैं इस लिंक प्रश्न के माध्यम से जाता हूं और jon skeet द्वारा उत्तर दिया गया है, उनका कहना है कि "थ्रेड एक अस्थिर चर को पढ़े बिना नहीं पढ़ सकता है कि क्या किसी अन्य थ्रेड ने कोई लेखन किया है।" लेकिन क्या होता है अगर एक धागा लिखने के संचालन के बीच में है और दूसरा धागा इसे पढ़ रहा है !! क्या मै गलत हु ?? क्या यह परमाणु ऑपरेशन पर दौड़ की स्थिति नहीं है ??
हार्डिक

3
@ हार्दिक: आप जो पूछ रहे हैं, उस पर अधिक प्रतिक्रियाएँ पाने के लिए कृपया एक और प्रश्न बनाएँ, यहाँ यह सिर्फ आप और मैं हैं और प्रश्न पूछने के लिए टिप्पणियाँ उपयुक्त नहीं हैं। एक नए प्रश्न का लिंक यहाँ पोस्ट करना न भूलें ताकि मैं फॉलो-अप कर सकूँ।
टॉमाज़ नर्कविक्ज़ 13

61

एक चर को अस्थिर के रूप में घोषित करने का अर्थ है कि इसके मूल्य को संशोधित करना तुरंत चर के लिए वास्तविक मेमोरी स्टोरेज को प्रभावित करता है। संकलक चर के लिए किए गए किसी भी संदर्भ को दूर नहीं कर सकता है। यह गारंटी देता है कि जब एक थ्रेड चर को संशोधित करता है, तो अन्य सभी थ्रेड नए मान को तुरंत देखते हैं। (यह गैर-वाष्पशील चर के लिए गारंटी नहीं है।)

एक परमाणु चर की घोषणा करते हुए कि चर पर किए गए संचालन एक परमाणु फैशन में होते हैं, अर्थात, ऑपरेशन के सभी विकल्प धागे के भीतर पूरे होते हैं जो वे निष्पादित होते हैं और अन्य थ्रेड्स द्वारा बाधित नहीं होते हैं। उदाहरण के लिए, एक वृद्धिशील-और-परीक्षण ऑपरेशन के लिए चर को बढ़ाने की आवश्यकता होती है और फिर दूसरे मूल्य की तुलना में; एक परमाणु ऑपरेशन यह गारंटी देता है कि ये दोनों चरण पूरे हो जाएंगे जैसे कि वे एक अविभाज्य / निर्बाध संचालन थे।

सभी एक्सेसरों को एक वेरिएबल में सिंक्रोनाइज़ करना, वेरिएबल को एक्सेस करने के लिए एक समय में केवल एक थ्रेड को अनुमति देता है, और अन्य सभी थ्रेड्स को उस एक्सेस के लिए प्रतीक्षा करने के लिए मजबूर करता है ताकि वह वेरिएबल तक अपनी पहुंच जारी कर सके।

सिंक्रोनाइज़्ड एक्सेस परमाणु पहुंच के समान है, लेकिन परमाणु संचालन आमतौर पर प्रोग्रामिंग के निचले स्तर पर लागू किया जाता है। इसके अलावा, केवल कुछ एक्सेस को एक वैरिएबल में सिंक्रोनाइज़ करना और अन्य एक्सेस को अनसिंक्रनाइज़ करने की अनुमति देना संभव है (उदाहरण के लिए, सभी राइट्स को वेरिएबल में सिंक्रोनाइज़ करें लेकिन इसमें से कोई भी रीड नहीं करता है)।

एटोमिसिटी, सिंक्रोनाइज़ेशन, और अस्थिरता स्वतंत्र गुण हैं, लेकिन आमतौर पर संयोजन तक पहुँचने के लिए उचित थ्रेड सहयोग को लागू करने के लिए संयोजन में उपयोग किया जाता है।

परिशिष्ट (अप्रैल 2016)

एक चर के लिए सिंक्रनाइज़ उपयोग आमतौर पर एक मॉनिटर या सेमाफोर का उपयोग करके कार्यान्वित किया जाता है । ये निम्न-स्तर के म्यूटेक्स (पारस्परिक बहिष्करण) तंत्र हैं जो एक धागे को विशेष रूप से किसी चर या ब्लॉक के नियंत्रण को प्राप्त करने की अनुमति देते हैं, अन्य सभी थ्रेड्स को प्रतीक्षा करने के लिए मजबूर करते हैं यदि वे भी उसी म्यूटेक्स को प्राप्त करने का प्रयास करते हैं। एक बार मालिक धागा म्यूटेक्स को छोड़ देता है, एक और धागा म्यूटेक्स को बदले में प्राप्त कर सकता है।

परिशिष्ट (जुलाई 2016)

किसी ऑब्जेक्ट पर सिंक्रनाइज़ेशन होता है । इसका मतलब यह है कि एक वर्ग की एक सिंक्रनाइज़ पद्धति thisको कॉल करने से कॉल की वस्तु लॉक हो जाएगी । स्टैटिक सिंक्रोनाइज़ किए गए तरीके Classऑब्जेक्ट को खुद ही लॉक कर देंगे ।

इसी तरह, एक सिंक्रनाइज़ ब्लॉक में प्रवेश करने thisके लिए विधि के ऑब्जेक्ट को लॉक करने की आवश्यकता होती है ।

इसका मतलब यह है कि एक सिंक्रनाइज़ किए गए तरीके (या ब्लॉक) को एक ही समय में कई थ्रेड्स में निष्पादित किया जा सकता है यदि वे अलग-अलग ऑब्जेक्ट्स पर लॉक कर रहे हैं, लेकिन केवल एक थ्रेड किसी भी एकल ऑब्जेक्ट के लिए एक समय में एक सिंक्रनाइज़ किए गए विधि (या ब्लॉक) को निष्पादित कर सकता है ।


25

अस्थिर:

volatileएक कीवर्ड है। volatileकैश के बजाय मुख्य मेमोरी से वेरिएबल का नवीनतम मूल्य प्राप्त करने के लिए सभी थ्रेड्स को बाध्य करता है। अस्थिर चर तक पहुंचने के लिए किसी लॉकिंग की आवश्यकता नहीं है। सभी धागे एक ही समय में अस्थिर चर मान तक पहुंच सकते हैं।

volatileचरों का उपयोग करने से मेमोरी की संगति त्रुटियों का खतरा कम हो जाता है, क्योंकि कोई भी अस्थिर चर लिखने वाला उसी चर के बाद के पठन के साथ होने से पहले संबंध स्थापित करता है।

इसका मतलब है कि एक परिवर्तनशील परिवर्तन volatileहमेशा अन्य थ्रेड्स को दिखाई देता है । क्या अधिक है, इसका मतलब यह भी है कि जब एक थ्रेड एक volatileचर को पढ़ता है , तो यह अस्थिरता के लिए न केवल नवीनतम परिवर्तन देखता है, बल्कि कोड के साइड इफेक्ट्स भी होते हैं जो परिवर्तन का नेतृत्व करते हैं

उपयोग कब करें: एक थ्रेड डेटा को संशोधित करता है और अन्य थ्रेड्स को डेटा का नवीनतम मूल्य पढ़ना होता है। अन्य थ्रेड्स कुछ कार्रवाई करेंगे लेकिन वे डेटा को अपडेट नहीं करेंगे

AtomicXXX:

AtomicXXXकक्षाएं एकल चर पर लॉक-फ्री थ्रेड-सुरक्षित प्रोग्रामिंग का समर्थन करती हैं। ये AtomicXXXकक्षाएं (जैसे AtomicInteger) मेमोरी असंगतता त्रुटियों / अस्थिर चर के संशोधन के साइड इफेक्ट्स को हल करती हैं, जिन्हें कई धागे में एक्सेस किया गया है।

कब उपयोग करें: एकाधिक थ्रेड्स डेटा को पढ़ और संशोधित कर सकते हैं।

सिंक्रनाइज़:

synchronizedकीवर्ड का उपयोग किसी विधि या कोड ब्लॉक की सुरक्षा के लिए किया जाता है। सिंक्रोनाइज़ करने की विधि के दो प्रभाव हैं:

  1. सबसे पहले, यह एक synchronizedही वस्तु पर इंटरलेव के लिए तरीकों के दो आह्वान के लिए संभव नहीं है । जब एक थ्रेड synchronizedकिसी ऑब्जेक्ट के लिए एक विधि निष्पादित कर रहा है, तो अन्य सभी थ्रेड्स जो synchronizedऑब्जेक्ट के साथ पहले थ्रेड को निष्पादित करने तक एक ही ऑब्जेक्ट ब्लॉक (सस्पेंड निष्पादन) के लिए तरीकों का आह्वान करते हैं।

  2. दूसरा, जब कोई synchronizedविधि बाहर निकलती है, तो यह स्वचालित रूप synchronizedसे उसी वस्तु के लिए विधि के किसी भी बाद के आह्वान के साथ एक होने से पहले संबंध स्थापित करता है । यह गारंटी देता है कि ऑब्जेक्ट की स्थिति में परिवर्तन सभी थ्रेड्स को दिखाई देते हैं।

कब उपयोग करें: एकाधिक थ्रेड्स डेटा को पढ़ और संशोधित कर सकते हैं। आपके व्यावसायिक तर्क न केवल डेटा को अपडेट करते हैं बल्कि परमाणु संचालन को भी निष्पादित करते हैं

AtomicXXXvolatile + synchronizedकार्यान्वयन के अलग होने के बावजूद भी समतुल्य है। चर + विधियों का AmtomicXXXविस्तार करता है, लेकिन सिंक्रनाइज़ेशन का उपयोग नहीं करता है।volatilecompareAndSet

संबंधित एसई प्रश्न:

जावा में अस्थिर और सिंक्रनाइज़ के बीच अंतर

वाष्पशील बूलियन बनाम एटॉमिक बुलियन

पढ़ने के लिए अच्छे लेख: (इन प्रलेखन पृष्ठों से ऊपर सामग्री ली गई है)

https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html

https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html


2
यह पहला उत्तर है जो वास्तव में वर्णित कीवर्ड / सुविधाओं के होने से पहले होने वाले शब्दों का उल्लेख करता है, जो यह समझने में महत्वपूर्ण हैं कि वे वास्तव में कोड निष्पादन को कैसे प्रभावित करते हैं। उच्च मत वाले उत्तर इस पहलू को याद करते हैं।
जिहोट

5

मुझे पता है कि दो धागे एक ही समय में सिंक्रोनाइज़ ब्लॉक में प्रवेश नहीं कर सकते हैं

दो थ्रेड एक ही ऑब्जेक्ट पर दो बार सिंक्रनाइज़ ब्लॉक में प्रवेश नहीं कर सकते हैं। इसका मतलब है कि दो धागे अलग-अलग वस्तुओं पर एक ही ब्लॉक में प्रवेश कर सकते हैं। यह भ्रम इस तरह कोड को जन्म दे सकता है।

private Integer i = 0;

synchronized(i) {
   i++;
}

यह अपेक्षा के अनुरूप व्यवहार नहीं करेगा क्योंकि यह हर बार एक अलग वस्तु पर ताला लगा सकता है।

अगर यह सच है कि यह atomic.incrementAndGet () बिना सिंक्रोनाइज़ के कैसे काम करता है ?? और धागा सुरक्षित है ??

हाँ। यह थ्रेड सुरक्षा प्राप्त करने के लिए लॉकिंग का उपयोग नहीं करता है।

यदि आप जानना चाहते हैं कि वे और अधिक विस्तार से कैसे काम करते हैं, तो आप उनके लिए कोड पढ़ सकते हैं।

और वाष्पशील चर / परमाणु चर के लिए आंतरिक पढ़ने और लिखने के बीच अंतर क्या है ??

परमाणु वर्ग अस्थिर क्षेत्रों का उपयोग करता है क्षेत्र में कोई अंतर नहीं है। अंतर प्रदर्शन किए गए कार्यों का है। एटॉमिक क्लासेस ComparAndSwap या CAS ऑपरेशन का उपयोग करते हैं।

मैंने कुछ लेख में पढ़ा कि धागे में चर की स्थानीय प्रति होती है, वह क्या है ??

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

यह केवल एक मुद्दा है जब मेमोरी साझा की जाती है कम से कम एक थ्रेड इसे अपडेट करता है।


@ अक्की ठाकुर क्या आप इस बारे में निश्चित हैं? पूर्णांक अपरिवर्तनीय है। इसलिए I ++ शायद इंट-इनबॉक्स को ऑटो-अनबॉक्स करेगा, इसे बढ़ाएगा, और फिर एक नया इंटेगर बनाएगा, जो पहले जैसा नहीं है। I अंतिम बनाने का प्रयास करें और i ++ को कॉल करते समय आपको संकलक त्रुटियां मिलेंगी।
फूफे 5

2

सिंक्रनाइज़ बनाम परमाणु बनाम वाष्पशील:

  • वाष्पशील और परमाणु केवल चर पर लागू होते हैं, जबकि सिंक्रनाइज़ किए गए विधि पर लागू होते हैं।
  • अस्थिरता दृश्यता के बारे में सुनिश्चित करती है कि परमाणुता / वस्तु की स्थिरता नहीं है, जबकि अन्य दृश्यता और परमाणुता के बारे में सुनिश्चित करते हैं।
  • रैम में अस्थिर चर स्टोर और यह पहुंच में तेज है लेकिन हम थ्रेड सुरक्षा या सिंक्रोनाइज़ेशन व्हाइटआउट सिंक्रोनाइज़्ड कीवर्ड को प्राप्त नहीं कर सकते हैं।
  • सिंक्रनाइज़ ब्लॉक या सिंक्रनाइज़ विधि के रूप में कार्यान्वित किया जाता है जबकि दोनों नहीं। हम सुरक्षित कीवर्ड की मदद से कोड की एक से अधिक लाइन को थ्रेड कर सकते हैं जबकि दोनों के साथ हम समान हासिल नहीं कर सकते।
  • सिंक्रोनाइज़्ड एक ही क्लास ऑब्जेक्ट या अलग क्लास ऑब्जेक्ट को लॉक कर सकता है जबकि दोनों नहीं कर सकते।

अगर कुछ भी छूट गया तो कृपया मुझे सुधार दें।


1

एक वाष्पशील + सिंक्रनाइज़ेशन एक ऑपरेशन (स्टेटमेंट) के लिए पूरी तरह से परमाणु होने के लिए एक मूर्ख प्रमाण समाधान है जिसमें सीपीयू के कई निर्देश शामिल हैं।

उदाहरण के लिए कहें: वाष्पशील int i = 2; i ++, जो कुछ भी नहीं है, लेकिन i = i + 1; जो इस कथन के निष्पादन के बाद स्मृति में मान 3 बनाता है। इसमें i (जो 2 है) के लिए मेमोरी से मौजूदा मूल्य को पढ़ना शामिल है, सीपीयू संचायक रजिस्टर में लोड करें और गणना के साथ मौजूदा मान को एक (2 + 1 = 3 के साथ संचयकर्ता) में लोड करें और फिर उस बढ़े हुए मूल्य को वापस लिखें। वापस स्मृति में। ये ऑपरेशन पर्याप्त रूप से परमाणु नहीं हैं, हालांकि इसका मूल्य मैं अस्थिर है। मैं अस्थिरता की गारंटी देता हूं कि स्मृति से पढ़ने / लिखने वाला व्यक्ति परमाणु है और MULTIPLE के साथ नहीं है। इसलिए, हमें मूर्ख प्रमाण परमाणु कथन रखने के लिए i ++ के आसपास भी सिंक्रनाइज़ करने की आवश्यकता है। इस तथ्य को याद रखें कि एक बयान में कई कथन शामिल हैं।

आशा है कि स्पष्टीकरण पर्याप्त स्पष्ट है।


1

जावा वाष्पशील संशोधक यह सुनिश्चित करने के लिए एक विशेष तंत्र का एक उदाहरण है कि संचार थ्रेड्स के बीच होता है। जब एक धागा एक अस्थिर चर को लिखता है, और दूसरा धागा उस लेखन को देखता है, तो पहला धागा दूसरे को मेमोरी की सभी सामग्रियों के बारे में बता रहा है जब तक कि वह उस अस्थिर चर को लिख नहीं देता।

परमाणु संचालन अन्य कार्यों के हस्तक्षेप के बिना कार्य की एक इकाई में किया जाता है। डेटा असंगति से बचने के लिए बहु-थ्रेडेड वातावरण में परमाणु संचालन आवश्यक है।

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