2013-08-08 9 views
8

मैं एक अपरिवर्तनीय डेटाटाइप बनाने की तलाश में था जिसमें अंतिम फ़ील्ड (एक सरणी शामिल है जो अंतिम सदस्य फ़ील्ड को सौंपे जाने से पहले बनाया गया है और भर चुका है), और देखा कि ऐसा लगता है कि JVM को यह गारंटी देने के लिए निर्दिष्ट किया गया है कि कोई अन्य थ्रेड जो इस ऑब्जेक्ट का संदर्भ प्राप्त करता है प्रारंभिक फ़ील्ड और सरणी मानों को देखेगा (मानते हैं कि this पर कोई पॉइंटर्स कन्स्ट्रक्टर के भीतर प्रकाशित नहीं हैं, What is an "incompletely constructed object"? और How do JVM's implicit memory barriers behave when chaining constructors? देखें)।अंतिम फ़ील्ड आंशिक रूप से निर्मित वस्तुओं को देखने से अन्य धागे को कैसे रोकते हैं?

मुझे उत्सुकता है कि यह इस ऑब्जेक्ट की हर पहुंच को सिंक्रनाइज़ किए बिना या अन्यथा कुछ महत्वपूर्ण प्रदर्शन दंड का भुगतान किए बिना कैसे हासिल किया जाता है। मेरी समझ के अनुसार, JVM निम्नलिखित कार्य करके इस लक्ष्य को हासिल कर सकते हैं:

  1. अंक निर्माता
  2. के अंत में एक लेख बाड़ ही लिखने-बाड़ के बाद नई वस्तु के संदर्भ में प्रकाशित
  3. समस्या एक रीड-बाड़ किसी भी समय आप एक वस्तु के अंतिम क्षेत्र का उल्लेख

मैं दूसरे सूत्र का खतरा को नष्ट करने अप्रारंभीकृत अंतिम क्षेत्रों (या के माध्यम से पुनरावर्ती संदर्भ को देखने का एक सरल या सस्ता तरीका नहीं सोच सकते हैं अंतिम क्षेत्र)।

ऐसा लगता है कि यह ऑब्जेक्ट पढ़ने वाले अन्य धागे में सभी पढ़ने-बाड़ के कारण एक गंभीर प्रदर्शन जुर्माना लगा सकता है, लेकिन रीड-बाड़ को समाप्त करने से संभावना है कि वस्तु संदर्भ किसी अन्य प्रोसेसर में देखा जाता है इससे पहले एक पठन-बाड़ जारी करता है या अन्यथा नए प्रारंभिक अंतिम फ़ील्ड के अनुरूप स्मृति स्थानों के अपडेट को देखता है।

क्या कोई जानता है कि यह कैसे काम करता है? और क्या यह एक महत्वपूर्ण प्रदर्शन जुर्माना पेश करता है?

+0

हटाए गए उत्तर से संबंधित स्पष्टीकरण: मेरे पास प्रदर्शन चिंताओं के लिए, मैं सामान्य रूप से अपरिवर्तनीय डेटा संरचनाओं से संबंधित एल्गोरिदमिक प्रदर्शन मुद्दों से चिंतित नहीं हूं, केवल झिल्ली निर्देशों के परिणामस्वरूप प्रदर्शन गिरावट के साथ। यह सच है कि एक थ्रेड "पता" सकता है कि इस तरह की किसी ऑब्जेक्ट को एक्सेस करते समय इसे पढ़ने-बाड़ जारी करने के बाद, उसे उसी ऑब्जेक्ट के लिए कोई अतिरिक्त रीड-बाड़ जारी नहीं करना पड़ता है, लेकिन यह स्पष्ट नहीं है कि यह कैसे किया जाता है या नहीं, या यदि "अंतिम फ़ील्ड प्रारंभिक" गारंटी प्राप्त करने का कोई अन्य तरीका है, तो मैं गारंटी नहीं दे सकता हूं। – jonderry

+0

समझा, इसलिए मैंने इसे हटा दिया। –

उत्तर

4

this writeup में "मेमोरी बाधाएं" अनुभाग देखें।

स्टोरस्टोर अंतिम फ़ील्ड सेट होने के बाद बाधा आवश्यक है और ऑब्जेक्ट संदर्भ किसी अन्य चर को सौंपा गया है। यह जानकारी का मुख्य भाग है जिसके बारे में आप पूछ रहे हैं।

"रीडरिंग" सेक्शन के अनुसार, अंतिम क्षेत्र की एक वस्तु को अंतिम फ़ील्ड वाले ऑब्जेक्ट के संदर्भ के स्टोर के साथ पुन: व्यवस्थित नहीं किया जा सकता है।

इसके अतिरिक्त, यह बताता है कि v.afield = 1; x.finalField = v; ... ; sharedRef = x; में, पहले दो में से तीसरे के संबंध में फिर से नहीं किया जा सकता है; जो सुनिश्चित करता है कि अंतिम फ़ील्ड के रूप में संग्रहीत किसी ऑब्जेक्ट के फ़ील्ड में स्टोर स्वयं को अंतिम फ़ील्ड वाले ऑब्जेक्ट के संदर्भ से पहले अन्य धागे के लिए दृश्यमान होने की गारंटी दी जाती है।

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

+0

यदि आप स्रोत के माध्यम से कुछ खोदना चाहते हैं, वैसे, कुछ लिंक और चर्चाएं हैं: ओपनजेडीके का कार्यान्वयन इस ईमेल के माध्यम से बिखरा हुआ है: http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/ 2012-फरवरी/007312.html - मैं इसे जानकारी के संक्षिप्त स्रोत के रूप में नहीं पोस्ट करता हूं, लेकिन विभिन्न प्लेटफार्मों पर कुछ कार्यान्वयन को देखने के लिए प्रारंभिक बिंदु के रूप में। –

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