Saturday 15 February 2014

java - Thread value not cached by threads even without volatile? -


  क्लास काउंटर {सार्वजनिक int i = 0; सार्वजनिक शून्य वेतन वृद्धि () {i ++; System.out.println ("मैं है" + i); System.out.println ("मैं / = 2 निष्पादन"); मैं = मैं 22 +; System.out.println ("मैं (I + 22 के बाद)" + i); System.out.println ("I + = 1 निष्पादन"); i ++; System.out.println ("मैं (i ++ के बाद)" + i); } सार्वजनिक शून्य कमी () (i--; System.out.println ("मैं है" + i); System.out.println ("मैं * = 2 निष्पादित"); मैं = मैं * 2; System.out.println ("मैं i * 2" + i के बाद है); System.out.println ("i- = 1 निष्पादन"); i = i-1; System.out.println ("मैं i-1 के बाद है" + i); } सार्वजनिक पूर्ण मूल्य () {वापसी i; }} वर्ग थ्रेड ए {सार्वजनिक थ्रेड ए (अंतिम काउंटर सी) {नया थ्रेड (नया रननाबल) (सार्वजनिक शून्य रन () {System.out.println ("थ्रेड A को बढ़ाने की कोशिश कर रहा है"); c.increment (); सिस्टम Out.println ("पूर्ण वृद्धि" + सीआई);}})। प्रारंभ (); }} वर्ग ThreadB {सार्वजनिक थ्रेडब (अंतिम काउंटर सी) {नया थ्रेड (नया रननाबल) (सार्वजनिक शून्य रन) {System.out.println ("थ्रेड बी की कमी की कोशिश कर रहा है"); c.decrement (); सिस्टम Out.println ("घटाव पूरा" + सीआई);}})। प्रारंभ (); }} वर्ग थ्रेड इंटरफेरेंस {सार्वजनिक स्थिर शून्य मुख्य (स्ट्रिंग अरिज []) अपवाद फेंकता {काउंटर सी = नया काउंटर (); नया थ्रेड ए (सी); नया थ्रेड बी (सी); }}   

उपरोक्त कोड में, थ्रेड ए को सबसे पहले काउंटर ऑब्जेक्ट तक पहुंच प्राप्त हुई और कुछ अतिरिक्त ऑपरेशंस के साथ वैल्यू बढ़ाया गया। थ्रेड ए में पहली बार के लिए मैं का कैश मूल्य नहीं है लेकिन i ++ (पहली पंक्ति में) के निष्पादन के बाद उसे मूल्य कैश मिलेगा। बाद में मूल्य पर अद्यतन किया जाता है और 24 हो जाता है। कार्यक्रम के अनुसार, चर के रूप में मैं अस्थिर नहीं है इसलिए परिवर्तन थ्रेड ए के स्थानीय कैश में किया जाएगा,

अब जब ThreadB घटता तक पहुंचता है () विधि I के मूल्य के रूप में ThreadA द्वारा अद्यतन 24 यानी यह कैसे संभव हो सकता है?

यह मानते हुए कि धागे प्रत्येक अद्यतन को नहीं देखेंगे जो अन्य थ्रेड साझा किए गए डेटा के रूप में मानते हैं कि सभी थ्रेड होगा एक दूसरे के अपडेट को तत्काल देखेगा।

महत्वपूर्ण बात यह है कि खाता लेना है संभावना अद्यतनों को देखने के लिए नहीं - इस पर भरोसा नहीं करना है।

अन्य धागे से अद्यतन नहीं देखे जाने के अलावा एक और मुद्दा है, आपको याद रखें - आपके सभी ऑपरेशन "पढ़ें, संशोधित करें, लिखो" अर्थ ... यदि कोई दूसरा थ्रेड आपके द्वारा इसे पढ़े जाने के बाद मान को संशोधित करता है, तो आप मूल रूप से इसे अनदेखा कर देंगे। उदाहरण के लिए, i 5 है जब हम इस रेखा तक पहुंचते हैं:

  i = i * 2;   

... लेकिन इसके माध्यम से आधा रास्ता, एक और थ्रेड इसे 4 में बदल देता है।

उस रेखा को इस तरह से सोचा जा सकता है:

  int tmp = i; टीएमपी = टीएमपी * 2; आई = टीएमपी;   

यदि दूसरा धागा "विस्तारित" संस्करण में पहली पंक्ति के बाद i को 4 में बदल देता है, तब भी अगर i अस्थिर है 4 लिखना अभी भी प्रभावी ढंग से खो जाएगा - क्योंकि उस बिंदु से, टीएमपी 5 है, यह दोगुना हो जाएगा 10, और फिर 10 लिखा जाएगा। < / html>

No comments:

Post a Comment