2014-12-25 8 views
15

जावा मेमोरी मॉडल के अनुसार, जब तक निष्पादन well-formed होता है तब तक निर्देशों को फिर से व्यवस्थित किया जा सकता है।क्या जावा रीडरिंग सिस्टम.currentTimeMillis() को प्रभावित करता है?

तो मुझे आश्चर्य है, क्या यह संभव है कि निम्नलिखित कोड निम्न आउटपुट उत्पन्न करते हैं?

[कोड] [एक ही धागे में]

long a = System.currentTimeMillis(); 
long b = System.currentTimeMillis(); 
long c = System.currentTimeMillis(); 

[उत्पादन]

a == 10, b == 20, c == 15 

संभव नहीं है, तो क्या JVM करता है/कार्यान्वयन ऐसा होने से रोकने के लिए क्या ?

+0

जब तक आप इसे 1 जनवरी 1 9 70 के करीब घड़ी सेट के साथ सिस्टम पर नहीं चलाते हैं, तो संभवतः आपको उन सटीक मान नहीं मिलेंगे। JVM उन निर्देशों को फिर से क्यों करेगा? –

+0

@ElliottFrisch हाय। उन सटीक मानों का उपयोग यह स्पष्ट करने के लिए किया जाता है कि ए, बी, और सी एकान्त रूप से बढ़ नहीं सकते हैं; 10, 20 और 15 होने की आवश्यकता नहीं है :-P –

+0

@ElliottFrisch मुझे यहां क्या चिंता है, क्या यह गारंटी है कि इन 3 System.currentTimeMillis() को JVM द्वारा पुन: व्यवस्थित नहीं किया जाएगा? –

उत्तर

5

कृपया यह प्रश्न Instruction reordering & happens-before relationship in java देखें।

मेरा मानना ​​है कि जब तक कि आप एक अलग धागे में न हों, किसी भी निष्पादन का नतीजा हमेशा आपके कोड के क्रम के अनुरूप होगा। इस स्थिति में, चूंकि इसे आदेश से संसाधित करना असंभव है, इसलिए यह भी अच्छा होना चाहिए कि आपके फ़ील्ड किसी अन्य धागे पर दिखाई दे।

+0

जोसेफ, आपके त्वरित उत्तर के लिए धन्यवाद। हालांकि, मुझे विश्वास है कि इन 3 निर्देशों को आदेश से निष्पादित किया जा सकता है, क्योंकि आवेषण विधियां जावा मेमोरी मॉडल द्वारा परिभाषित एक क्रिया नहीं है, फिर इन 3 निर्देशों के लिए संबंध पहले मौजूद नहीं होता है। यदि int = = 1 + 1, int b = 2 + 2 को एक ही थ्रेड में पुन: व्यवस्थित किया जा सकता है और int b = 2 + 2, int a = 1 + 1 के रूप में निष्पादित किया जा सकता है, तो System.currentTimeMillis() का विशेष क्या है उन्हें क्रम में निष्पादित किया जाना चाहिए? –

+0

प्रैक्टिस में, 'currentTimeMillis' को या तो "यह बाहरी कॉल है, इसलिए मुझे नहीं पता कि यह क्या करता है और मैं इसे फिर से ऑर्डर नहीं करूंगा"। अन्यथा मान लीजिए कि पुनर्गठनकर्ता जानता है कि यह कैसे काम करता है, अगर यह विधि पूरी तरह जावा में लागू की जाएगी तो इसे कुछ अस्थिर चर (सिस्टम घड़ी) को पढ़ना होगा। किसी भी तरह से, इसे फिर से आदेश नहीं दिया जाना चाहिए। – Sebi

+0

@ सेबी, मुझे आपकी अनुमान पसंद है; कोई संदर्भ इसे साबित कर सकता है? –

1

उपयोगकर्ता सिस्टम कॉल होने के कारण, कंपाइलर्स को उन्हें उसी थ्रेड में पुन: व्यवस्थित नहीं करना चाहिए। यदि यह सत्य नहीं था, तो हम System.out.println (स्वतंत्र मान) में पुनरावृत्ति प्रभाव का अनुभव भी कर सकते थे; मुझे लगता है कि सिस्टम की/ओएस की घड़ी तक पहुंच इन परिचालनों (हमेशा मौजूदा धागे के लिए) के बीच एक तरह का रिश्ता बनाती है, इसलिए सैद्धांतिक रूप से उनके बीच कुछ निर्भरता है। शायद, JVM इस समस्या को मानता है और उपयोगकर्ता सिस्टम कॉल को कभी भी प्रतिबिंबित नहीं करता है।

+0

कौन कहता है कि वर्तमान टाइममिलिस सिस्टम कॉल है? यह एक कार्यान्वयन विस्तार है। – usr

+0

यह एक कार्यान्वयन विस्तार हां है, लेकिन वास्तव में वर्तमान कार्यान्वयन यह सिस्टम संसाधनों का उपयोग नहीं करता है? यदि हां, तो यह JVM द्वारा सेंसर किया जा सकता है और पुनरावृत्ति से बचाता है। यदि डिफ़ॉल्ट कार्यान्वयन में सिस्टम कॉल चीजें शामिल नहीं हो सकतीं तो शायद अलग हो। –

+0

क्या आप कह रहे हैं कि 'मूल' विधि कॉल का पुन: आदेश नहीं दिया जा सकता है? –

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