2009-12-14 4 views
15

एक सी ++ प्रोग्रामर जावा के साथ अधिक परिचित होने के नाते, यह किसी भी तरह की घोषणा के बिना मनमानी वस्तुओं को लॉक करने के लिए भाषा स्तर समर्थन देखने के लिए थोड़ा अजीब बात है कि वस्तु इस तरह के लॉकिंग का समर्थन करती है। प्रत्येक ऑब्जेक्ट के लिए म्यूटेक्स बनाना एक भारी लागत की तरह लगता है जिसे स्वचालित रूप से चुना जा सकता है। स्मृति उपयोग के अलावा, म्यूटेक्स कुछ प्लेटफार्मों पर ओएस सीमित संसाधन हैं। यदि म्यूटेक्स उपलब्ध नहीं हैं तो आप लॉक स्पिन कर सकते हैं लेकिन इसकी प्रदर्शन विशेषताओं में काफी भिन्नता है, जो मैं पूर्वानुमानितता को चोट पहुंचाने की अपेक्षा करता हूं।क्या JVM 'सिंक्रनाइज़ किए गए' कीवर्ड को लागू करने के लिए प्रत्येक ऑब्जेक्ट के लिए एक म्यूटेक्स बनाता है? यदि नहीं, तो कैसे?

क्या सभी मामलों में JVM स्मार्ट पर्याप्त है यह पहचानने के लिए कि कोई विशेष वस्तु सिंक्रनाइज़ किए गए कीवर्ड का लक्ष्य कभी नहीं रहेगी और इस प्रकार म्यूटेक्स बनाने से बचें? म्यूटेक्स को आलसी बनाया जा सकता है, लेकिन यह एक बूटस्ट्रैपिंग समस्या उत्पन्न करता है जो खुद को एक म्यूटेक्स की आवश्यकता होती है, और यहां तक ​​कि अगर यह काम किया जाता है तो भी मुझे लगता है कि यह अभी भी कुछ ओवरहेड होने जा रहा है यह ट्रैक करने के लिए कि क्या म्यूटेक्स पहले से ही बनाया गया है या नहीं। इसलिए मुझे लगता है कि ऐसा अनुकूलन संभव है, यह संकलन समय या स्टार्टअप पर किया जाना चाहिए। सी ++ में संकलन मॉडल के कारण ऐसा अनुकूलन संभव नहीं होगा (आप नहीं जानते कि किसी ऑब्जेक्ट के लिए लॉक लाइब्रेरी सीमाओं में उपयोग किया जा रहा था), लेकिन मुझे जावा के संकलन और जानने के लिए लिंक करने के बारे में पर्याप्त जानकारी नहीं है यदि एक ही सीमा लागू होती है।

+0

मुझे यकीन है कि ओएस-स्तरीय संसाधनों पर भरोसा करने के बजाय, आंतरिक रूप से 'सिंक्रनाइज़' को JVM में आंतरिक रूप से संभाला जाता है। –

+0

यह पूरी तरह से सच नहीं हो सकता है। मैं सहमत हूं कि इसे किसी भी तरह से JVM चाहता है, लेकिन JVM को आंतरिक रूप से कहीं भी ओएस-स्तरीय संचार पर निर्भर होना चाहिए। आप अपने स्वयं के म्यूटेक्स वर्ग को लिख सकते हैं जो ताले स्पिन करते हैं, लेकिन यदि आप ओएस शेड्यूलर को थ्रेड को सोने के लिए रखना चाहते हैं और उन्हें उचित तरीके से जगा सकते हैं, तो किसी बिंदु पर आपको ओएस को अपने म्यूटेक्स के बारे में बताना होगा, और ऐसे रजिस्ट्रेशन सीमित हैं संसाधन। –

+0

आपको अपने म्यूटेक्स के बारे में ओएस को बताने की आवश्यकता नहीं है - आपको केवल यह बताने की ज़रूरत है कि कुछ धागे को जागने की आवश्यकता है। –

उत्तर

15

कोई है जो रास्ता है कि कुछ JVMs ताले को लागू को देखा है के रूप में बोलते हुए ...

सामान्य दृष्टिकोण ऑब्जेक्ट के हेडर शब्द में कुछ आरक्षित बिट्स के साथ शुरू करना है। यदि ऑब्जेक्ट कभी लॉक नहीं होता है, या यदि यह लॉक है, लेकिन इसमें कोई विवाद नहीं है, यह उस तरह से रहता है। यदि लॉक ऑब्जेक्ट पर विवाद होता है, तो JVM को पूर्ण-उड़ा हुआ म्यूटेक्स डेटा संरचना में लॉक करता है, और यह ऑब्जेक्ट के जीवनकाल के लिए उस तरह से रहता है।

EDIT - मैंने अभी देखा है कि ओपी ओएस समर्थित समर्थित म्यूटेक्स के बारे में बात कर रहा था। उदाहरणों में मैंने देखा है, अनफ्लुएंटेड म्यूटेक्स सीधे सीएएस निर्देशों का उपयोग करके लागू किए गए थे और जैसे, पर्थ्रेड लाइब्रेरी फ़ंक्शंस आदि का उपयोग करने के बजाय

+0

फुलाकर, क्या आपका मतलब सी/सी ++ में छोटे स्ट्रिंग अनुकूलन की तरह कुछ चल रहा है? (http://tulrich.com/rants-2009.html#d2009-01-03T00:00:00Z) असल में, यह जानकारी किसी शब्द के अंदर पैक की गई बिट्स के रूप में शुरू होती है, लेकिन जब कुछ शर्तों को पूरा किया जाता है तो उस शब्द का अर्थ शुरू होता है अधिक क्षेत्रों के साथ एक वस्तु के लिए एक सूचक के रूप में? –

+0

संकल्पनात्मक रूप से, हां। –

+1

केवल सीएएस निर्देशों का उपयोग करके, आप थ्रेड को सोने के लिए ओएस शेड्यूलर कैसे प्राप्त करते हैं? –

2

आप कभी भी यह सुनिश्चित नहीं कर सकते कि किसी ऑब्जेक्ट को लॉक के रूप में कभी भी उपयोग नहीं किया जाएगा (प्रतिबिंब पर विचार करें)। आम तौर पर प्रत्येक ऑब्जेक्ट में लॉक को समर्पित कुछ बिट्स के साथ एक शीर्षलेख होता है। इसे कार्यान्वित करना संभव है कि हेडर केवल आवश्यकतानुसार जोड़ा जाता है, लेकिन यह थोड़ा जटिल हो जाता है और आपको शायद कुछ शीर्षलेख की आवश्यकता होती है (कक्षा ("vtbl" के बराबर और सी ++ में आवंटन आकार), हैश कोड और कचरा संग्रह) ।

Here's a wiki page on the implementation of synchronisation in the OpenJDK.

(मेरी राय में, एक गलती हर वस्तु के लिए एक लॉक जोड़ने था।)

+0

क्या कहीं कहीं मैं इस 'हेडर' के बारे में अधिक पढ़ सकता हूं? चूंकि आप कहते हैं कि आपको शायद इसकी आवश्यकता होगी वैसे भी मुझे लगता है कि यह लॉकिंग के अलावा अन्य चीजों के लिए उपयोग किया जाता है। –

+0

यह सब जीपीएल/जेआरएल/जेआईयूएल स्रोत में है! –

+0

सच है, लेकिन मैं उम्मीद कर रहा था कि यदि जावा प्रोग्रामर सामान्य रूप से इन सवालों के जवाब में रूचि रखते हैं तो मुझे लगता है कि किसी ने स्रोत कोड की लाखों लाइनों की तुलना में कुछ और आसानी से पचाने योग्य लिखा है। अगर मैं काफी दिलचस्पी लेता हूं और पर्याप्त समय होता हूं तो मैं अंततः ऐसा कर सकता हूं;) –

2

यह वास्तव में जेवीएम का कार्यान्वयन विवरण है, और विभिन्न जेवीएम इसे अलग-अलग कार्यान्वित करें। हालांकि, यह निश्चित रूप से कुछ ऐसा नहीं है जिसे संकलित समय पर अनुकूलित किया जा सकता है, चूंकि जावा रनटाइम पर लिंक करता है, और यह पुराने कोड में बनाए गए ऑब्जेक्ट को पकड़ने के लिए पहले अज्ञात कोड के लिए संभव है और उस पर सिंक्रनाइज़ करना प्रारंभ करना संभव है।

ध्यान दें कि जावा लिंगो में, सिंक्रनाइज़ेशन आदिम को म्यूटेक्स के बजाय "मॉनीटर" कहा जाता है, और यह विशेष बाइटकोड संचालन द्वारा समर्थित है। here की एक विस्तृत विस्तृत व्याख्या है।

+0

अच्छा लिंक, धन्यवाद। –

1

जेवीएम सीधे तुलना-और-स्वैप निर्देश का उपयोग नहीं कर सकता है?मान लीजिए कि प्रत्येक वस्तु के एक क्षेत्र lockingThreadId धागा है कि यह ताला लगा की आईडी भंडारण है चलो,

while(compare_and_swap (obj.lockingThreadId, null, thisThreadId) != thisTheadId) 
    // failed, someone else got it 
    mark this thread as waiting on obj. 
    shelf this thead 

//out of loop. now this thread locked the object 

do the work 

obj.lockingThreadId = null; 
wake up threads waiting on the obj 
इस

एक खिलौना मॉडल है, लेकिन यह बहुत महंगा प्रतीत नहीं होता है, और कोई ओएस पर भरोसा करता है।

+1

पीएस किसी ऑब्जेक्ट को लॉक होने की अनुमति देने की डिज़ाइन पसंद शायद गलत है। शायद सिंक उद्देश्य के लिए केवल कुछ प्रकार की वस्तुओं की अनुमति दी जानी चाहिए, जैसे कि केवल कुछ प्रकार की वस्तुओं को फेंक दिया जा सकता है। 'सिंक्रनाइज़ (a_normal_object) {}' नए शिक्षार्थियों के लिए बहुत भ्रमित है, उन्होंने सोचा कि इस प्रकार वस्तु सुरक्षित है और कोई अन्य धागा इसे लिख नहीं सकता है। अगर उन्हें अपनी सामान्य वस्तु की सुरक्षा के लिए एक अलग लॉक ऑब्जेक्ट का उपयोग करना है, तो यह समझना आसान होगा कि क्या हो रहा है। – irreputable

+1

जेवी को किसी बिंदु पर ओएस के साथ संवाद करने के लिए थ्रेड प्राप्त करने के लिए और इसे फिर से उठाने में सक्षम होने के लिए, क्योंकि ओएस शेड्यूलर इसके लिए ज़िम्मेदार है। यदि JVM इसे सीधे उपयोग करता है, तो सभी प्रतीक्षा स्पिन ताले होंगे, जो लंबे इंतजार के लिए अक्षम हैं। एक वास्तविक कार्यान्वयन शायद थोड़ी देर के लिए स्पिन करता है तो ओएस से वास्तविक सेमफोर पर सो जाता है। –

+0

"यदि JVM इसे सीधे उपयोग करता है" <- by 'it' मेरा मतलब है सीएएस निर्देश –

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

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