2012-10-12 10 views
34

निम्नलिखित वर्ग को देखते हुए:वापसी समवर्ती कोड में असाइनमेंट ऑपरेटर का मूल्य

class Foo { 
    public volatile int number; 

    public int method1() { 
    int ret = number = 1; 
    return ret; 
    } 

    public int method2() { 
    int ret = number = 2; 
    return ret; 
    } 
} 

और दिए गए कई एक ही Foo उदाहरण पर समवर्ती method1() और method2() बुला धागे, Method1 के लिए एक कॉल() कभी लौट सकते हैं के अलावा और कुछ 1?

उत्तर

10

JLS 15.26 निर्दिष्ट:

12 असाइनमेंट ऑपरेटरों रहे हैं; सभी वाक्य रचनात्मक रूप से सही-सहयोगी हैं (वे दाएं से बाएं समूह)। इस प्रकार, ए = बी = सी का मतलब है = (बी = सी), जो सी से बी के मान को निर्दिष्ट करता है और उसके बाद बी के मान को असाइन करता है।

टेड होप के उत्तर से पता चलता है कि सूर्य का जावैक इस व्यवहार का पालन नहीं करता है, संभवत: अनुकूलन के रूप में।

यहां थ्रेडिंग के कारण, विधि 1 का व्यवहार अपरिभाषित होगा। यदि सूर्य का कंपाइलर व्यवहार को निरंतर बनाता है तो यह अपरिभाषित व्यवहार से नहीं टूटता है।

+0

क्या इस अनुकूलन को ['अस्थिर 'फ़ील्ड] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.4) के लिए अनुमति दी जा सकती है? – trashgod

+0

हालांकि मैं उत्सुक हूं, अगर यह कल्पना का इरादा है। मुझे लगता है कि उन्होंने बी को निर्दिष्ट किया हो सकता है "और उसके बाद बी के मान को असाइन किया जा सकता है" बस इसे इस मामले में साफ़ करने के लिए कि ए, बी और सी के विभिन्न प्रकार हैं (आदिम अभिन्न/फ़्लोटिंग प्रकार कहें) और रूपांतरण होते हैं, असाइनमेंट तब होता है जब परिवर्तित मूल्य का उपयोग किया गया था। उदा।, अगर ए और सी युगल थे और बी एक फ्लोट था। – BeeOnRope

+0

@BeeOnRope यह काफी संभव है - कि जेएलएस पृष्ठ अस्थिर क्षेत्रों की तुलना में प्रकार रूपांतरणों के साथ अधिक चिंतित प्रतीत होता है। – Bringer128

15

मुझे लगता है कि उत्तर संकलक पर निर्भर करता है। भाषा specifies:

रन-टाइम पर, असाइनमेंट अभिव्यक्ति का परिणाम असाइनमेंट के बाद परिवर्तनीय का मान है।

मुझे लगता है कि सैद्धांतिक रूप से मूल्य दूसरे (बाएं) असाइनमेंट होने से पहले बदला जा सकता है।

0: aload_0 
1: iconst_1 
2: dup_x1 
3: putfield  #2; //Field number:I 
6: istore_1 
7: iload_1 
8: ireturn 

यह ढेर और यह भार पर निरंतर 1number में ret में डुप्लिकेट और फिर ret लौटने से पहले:

हालांकि, सूर्य की javac संकलक के साथ, method1 में बदल जाएगा होगा। इस मामले में, इससे कोई फर्क नहीं पड़ता कि number में संग्रहीत मान ret पर असाइनमेंट से पहले संशोधित किया गया है, क्योंकि 1, number असाइन नहीं किया जा रहा है।

+0

के प्रकार के माध्यम से असाइन किया गया है भाषा भ्रामक है संभव है? – BeeOnRope

+0

बाइटकोड निश्चित रूप से दिलचस्प है, लेकिन यह साबित नहीं करता है कि spec द्वारा _required_ क्या है। – BeeOnRope

+0

@BeeOnRope - सतह पर, मुझे लगता है कि संकलक द्वारा उत्पन्न कोड कड़ाई से भाषा की कल्पना के अनुसार नहीं है। हालांकि, यह हो सकता है कि "असाइनमेंट के बाद" का अर्थ है "तत्काल बाद" और अन्य धागे से परिवर्तनीय में कोई और परिवर्तन परिणाम को प्रभावित नहीं करता है। अगर इसका मतलब है (और यह मुझे स्पष्ट नहीं है कि यह है), तो जावैक सही कोड उत्पन्न कर रहा है, इन्सुलेट समवर्ती परिवर्तनों से मूल्य 'संख्या' तक। –

5

या तो कथन में अस्थिर पढ़ने होता है, या इसमें अस्थिर पढ़ने नहीं होता है। यहां कोई अस्पष्टता नहीं हो सकती है, क्योंकि प्रोग्राम अर्थशास्त्र के लिए अस्थिर पढ़ने बहुत महत्वपूर्ण है।

यदि जावा पर भरोसा किया जा सकता है, तो हम निष्कर्ष निकाल सकते हैं कि कथन में number का अस्थिर पढ़ने शामिल नहीं है। असाइनमेंट अभिव्यक्ति का मान x=y वास्तव में केवल y (रूपांतरणों के बाद) का मान है।

हम यह भी मान सकते हैं कि

System.out.println(number=1); 

पढ़ने number

String s; 

    (s="hello").length(); 
को शामिल नहीं करता

पढ़ने s

x_1=x_2=...x_n=v 
को शामिल नहीं करता

x_n, x_n-1, ... पढ़ने को शामिल नहीं करता; क्योंकि यह, सूचित करते हैं कि चर के "मूल्य" प्रयोग किया जाता है लगता है यह सूचित करते हैं एक दूसरे पढ़ने है कि प्रतीयमान बजाय, v का मूल्य सीधे x_i (करने के लिए आवश्यक रूपांतरण के बाद x_n, ... x_i

+0

मुझे आशा है कि आप सही हैं, लेकिन कल्पना निश्चित रूप से उस व्याख्या को अधिक भार नहीं देती है, है ना? मुझे लगता है अस्थिर एक लाल हेरिंग है। इसमें एक अस्थिर पढ़ा जा सकता है, और अभी भी थ्रेडिंग के साथ अजीब चीजें करते हैं (अस्थिर मतलब है कि कुछ चीजें होनी चाहिए, लेकिन एक ही चीजें * सामान्य पढ़ने के साथ हो सकती हैं)। – BeeOnRope

+0

यह उत्तर अभ्यास में मेरे लिए सही लगता है।जेएलएस विशेष रूप से बताता है कि 'ए = बी = सी' 'बी = सी के बराबर है; ए = बी; 'लेकिन ऐसा लगता है कि इसे' बी = सी 'के रूप में लागू किया गया है; एक = सी; 'धीमी अस्थिर क्षेत्र पुनर्प्राप्ति की आवश्यकता को रोकने के लिए। इसके साथ ही, उद्धृत जेएलएस संदर्भ * * संकलक को यह * संदर्भ करना चाहिए, बल्कि एक खराब उदाहरण हो सकता है। – Bringer128

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