2010-04-05 10 views
41

पर एक परमाणु संदर्भ लिख रहा है जावा मेमोरी मॉडल अनिवार्य है कि int लिखना परमाणु है: यानी, यदि आप इसे एक मान में लिखते हैं (4 बाइट्स से युक्त) एक थ्रेड में लिखते हैं और इसे दूसरे में पढ़ते हैं, तो आप सभी बाइट्स या कोई भी प्राप्त करें, लेकिन कभी भी 2 नए बाइट्स और 2 पुराने बाइट्स या ऐसे नहीं।64 बिट वीएम

यह long के लिए गारंटी नहीं है। यहां 0x1122334455667788 लिखने वाले चर के लिए 0 लिखने से पहले 0x112233440000000 या 0x0000000055667788 पढ़ने वाले दूसरे थ्रेड में परिणाम हो सकता है।

अब विनिर्देश वस्तु संदर्भों को या तो int या लंबे आकार के होने के लिए जरूरी नहीं है। सुरक्षा कारणों के लिए मुझे संदेह है कि उन्हें परमाणु रूप से लिखा जाने की गारंटी है, लेकिन 64 बिट वीएम पर ये संदर्भ 64 बिट मान (केवल स्मृति पते) के बहुत अच्छे हो सकते हैं।

अब यहाँ मेरे प्रश्न हैं:

  • कोई स्मृति मॉडल को कवर यह (है कि मैं नहीं मिला है) चश्मा हैं?
  • लंबे समय से लिखने वाले संदिग्ध 64 बिट वीएम पर परमाणु होने के लिए संदिग्ध हैं?
  • क्या वीएम को 32 बिट के संदर्भों को मानचित्रित करने के लिए मजबूर किया गया है?

सादर, स्टीफन

+2

@Steffen हील: nitpicking लेकिन ध्यान दें कि सभी संदर्भ (अपशिष्ट 64 बिट संदर्भ पैदा कर रहे हैं की अद्भुत मात्रा के कारण) 64 बिट आंतरिक रूप से भी 64 बिट वी एम पर हैं।आधुनिक वीएम पॉइंटर संपीड़न/संदर्भ संपीड़न का उपयोग कर रहे हैं जिन्हें "संपीड़ित" कहा जाता है *: http://wikis.sun.com/display/HotSpotInternals/CompressedOops इसलिए मैं असहमत नहीं हूं कि वे * 64 बिट मान हो सकते हैं लेकिन वे अक्सर होते हैं 'टी (यह नहीं कि यह डिर्क पोस्ट किए गए उत्तर में बहुत कुछ बदलता है)। – SyntaxT3rr0r

उत्तर

52

देखें JLS section 17.7: Non-atomic Treatment of double and long

जावा प्रोग्रामिंग भाषा स्मृति मॉडल के प्रयोजनों के लिए, एक गैर अस्थिर लंबे या डबल मूल्य के लिए एक एकल लिखने दो के रूप में व्यवहार किया जाता है अलग लिखते हैं: प्रत्येक 32-बिट आधे में से एक। इसका परिणाम स्थिति हो सकता है जहां एक थ्रेड से एक 64-बिट मान के पहले 32 बिट्स को एक लिखता है, और दूसरा 32 बिट्स अन्य लिखने से देखता है।

अस्थिर लंबे और दोहरे मूल्यों के लेखन और पढ़ना हमेशा परमाणु होते हैं।

पर ध्यान दिए बिना, संदर्भों को लिखने और पढ़ने के लिए हमेशा परमाणु होते हैं, चाहे वे 32-बिट या 64-बिट मानों के रूप में लागू हों।

कुछ कार्यान्वयन यह सुविधाजनक आसन्न 32-बिट मूल्यों पर दो लिखने कार्रवाई में एक 64-बिट लंबे या डबल मूल्य पर एक भी लिखने कार्रवाई विभाजित करने के लिए मिल सकता है। दक्षता के लिए, यह व्यवहार कार्यान्वयन-विशिष्ट है; जावा वर्चुअल मशीन का कार्यान्वयन परमाणु रूप से या दो भागों में लिखने के लिए स्वतंत्र है।

जावा वर्चुअल मशीन के कार्यान्वयन को से 64-बिट मानों को विभाजित करने से बचने के लिए प्रोत्साहित किया जाता है। प्रोग्रामर को को प्रोत्साहित किया जाता है कि साझा जटिलताओं से बचने के लिए साझा किए गए 64-बिट मानों को अस्थिर या उनके प्रोग्राम को सिंक्रनाइज़ करें।

(जोर जोड़ा)

+0

ठीक है, मैं फिर से चश्मा में बिंदु चूक गया। मुझे लगता है, मैं बहुत थक गया हूं और सवाल पूछने के बजाय सोना चाहिए ... सूचक के लिए धन्यवाद। (AGAIN) –

+1

यदि "संदर्भों को लिखना और पढ़ना हमेशा परमाणु है, भले ही उन्हें 32 या 64 बिट मानों के रूप में लागू किया गया हो।", हमारे पास कक्षा परमाणु संदर्भ क्यों है (https://docs.oracle.com/javase/ 7/docs/api/जावा/util/समवर्ती/परमाणु/AtomicReference.html)? केवल विधियों के कारण प्राप्त करें और तुलना करें और तुलना करें और सेट करें? –

+0

टूटा संदर्भ मान नहीं देख रहा तस्वीर का केवल एक हिस्सा है। 'परमाणु संदर्भ' मुख्य रूप से इसके सिंक्रनाइज़ेशन एपीआई ('तुलना और सेट' जिसे आपने बताया है), @ mc.android.developer के लिए मौजूद है, और यहां कोई "केवल" नहीं है। यह वास्तव में महत्वपूर्ण हिस्सा है। – Dirk