2012-06-25 17 views
10

मुझे जावा सिंक्रनाइज़ेशन के बारे में कोई संदेह है। मैं जानना चाहता हूं कि मेरे वर्ग में तीन सिंक्रनाइज़ किए गए तरीके हैं और एक थ्रेड एक सिंक्रनाइज़ विधि में लॉक प्राप्त करता है अन्य दो लॉक हो जाएंगे? मैं इस सवाल से पूछ रहा हूं क्योंकि मैं निम्नलिखित कथन से उलझन में हूं।जावा में सिंक्रनाइज़ेशन कैसे काम करता है?

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

+1

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

+0

पुन: "... अन्य दो लॉक हो जाएंगे"। वर्तमान में लॉक होने वाले वर्तमान में थ्रेड को उसी ऑब्जेक्ट पर एक और सिंक्रनाइज़ विधि को कॉल करने से रोका नहीं जाएगा, हालांकि किसी अन्य थ्रेड को अवरुद्ध कर दिया जाएगा (यानी लॉक दिए जाने तक प्रतीक्षा करने के लिए मजबूर होना चाहिए)। मैक्स का एक अच्छा जवाब है जो इस बारे में बात करता है कि आप ऑब्जेक्ट पर लॉक कर रहे हैं या नहीं (यानी यह) या अन्य ऑब्जेक्ट वैरिएबल पूरी तरह से। – Brad

उत्तर

7

जावा में सिंक्रनाइज़ेशन कुछ विशिष्ट ऑब्जेक्ट पर मॉनिटर को एक्वायर करने के माध्यम से किया जाता है। इसलिए, आप ऐसा करते हैं, तो:

class TestClass { 
    SomeClass someVariable; 

    public void myMethod() { 
     synchronized (someVariable) { 
      ... 
     } 
    } 

    public void myOtherMethod() { 
     synchronized (someVariable) { 
      ... 
     } 
    } 
} 

फिर उन दो ब्लॉकों को किसी भी समय 2 अलग धागे के निष्पादन के द्वारा संरक्षित किया जाएगा, जबकि someVariable संशोधित नहीं है। असल में, ऐसा कहा जाता है कि उन दो ब्लॉक को चर someVariable के विरुद्ध सिंक्रनाइज़ किया गया है।

जब आप विधि पर synchronized डालते हैं, तो इसका मूल रूप से synchronized (this) जैसा होता है, यानी इस विधि को निष्पादित करने वाले ऑब्जेक्ट पर सिंक्रनाइज़ेशन होता है।

यही कारण है:

public synchronized void myMethod() { 
    ... 
} 

मतलब एक ही है:

public void myMethod() { 
    synchronized (this) { 
     ... 
    } 
} 

इसलिए, अपने सवाल का जवाब देने - हाँ, धागे एक साथ अलग धागे में उन तरीकों कॉल करने के लिए सक्षम नहीं होगा, क्योंकि वे दोनों एक ही मॉनीटर का संदर्भ रखते हैं, this ऑब्जेक्ट की निगरानी।

+0

अधिकतम, आपके अंतिम वाक्य में "लॉक" शब्द भ्रामक है। मुझे लगता है कि आप कहने के लिए "... क्योंकि वे दोनों एक ही मॉनीटर का संदर्भ रखते हैं"। दो थ्रेड एक ही मॉनिटर से एक ही समय में लॉक नहीं रख सकते हैं। – Brad

+0

@Brad सुधार के लिए धन्यवाद, अद्यतन किया गया। – bezmax

+0

पहले पैराग्राफ में जो आपने बताया है उसे प्राप्त नहीं कर रहा है, क्या आप इसे सरल शर्तों की व्याख्या कर सकते हैं। – userab

1

हां द्वारा किसी भी समय बुलाया जा सकता है।
सिंक्रनाइज़ किए गए विधि थ्रेड को निष्पादित करने के लिए ऑब्जेक्ट पर लॉक प्राप्त करने की आवश्यकता है और एक समय में केवल एक थ्रेड ऑब्जेक्ट पर लॉक प्राप्त कर सकता है।

0

प्रत्येक जावा ऑब्जेक्ट (क्लास इंस्टेंस) में एक म्यूटेक्स ऑब्जेक्ट होता है। एक विधि के सामने सिंक्रनाइज़ किए गए कीवर्ड का अर्थ है कि चलने वाले थ्रेड को उस ऑब्जेक्ट के लिए mutex पर लॉक प्राप्त करना होता है। वास्तव में,

public synchronized doSomething(){ 
    ... 
} 

वास्तव में इस रूप में एक ही है:

public doSomething(){ 
    synchronized(this){ 
     ... 
    } 
} 

तो हाँ, वहाँ केवल एक ही धागा वर्ग उदाहरण प्रति एक तुल्यकालन विधि को क्रियान्वित किया जाएगा।

ध्यान दें कि कभी-कभी यह उप-शीर्ष हो सकता है, क्योंकि आप संशोधनों की रक्षा करना चाहते हैं, लेकिन समवर्ती पाठ के बजाय ठीक है, इस मामले में, सिंक्रनाइज़ किए गए कीवर्ड की बजाय, आप ReadWriteLock देख सकते हैं।

-1

मुझे यकीन नहीं है कि आपको भ्रमित करने में क्या मिल रहा है, लेकिन लॉक को अन्य थ्रेड को प्राप्त करने के दौरान इसे प्राप्त करने से रोकता है, और कक्षा के सभी गैर स्थैतिक सिंक्रनाइज़ किए गए तरीके एक ही ऑब्जेक्ट पर सिंक्रनाइज़ करते हैं, इसलिए उत्तर आपके प्रश्न के लिए 'हां' है, मानते हुए कि मैंने आपको सही ढंग से समझा है। मुझे नहीं पता कि 'सिंक्रनाइज़' का अर्थ क्या हो सकता है, या इसका उपयोग किसी भी अन्य अर्थ के साथ होगा।

0

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

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

0

हां, सभी धागे लेकिन लॉक प्राप्त करने वाले व्यक्ति को तब तक इंतजार करना होगा जब तक कि लॉक फिर से रिलीज़ नहीं हो जाता है ताकि तीन सिंक्रनाइज़ किए गए तरीकों में से एक को निष्पादित किया जा सके।

याद रखें, एक तुल्यकालन विधि एक ही है एक सामान्य विधि के रूप में द्वारा

synchronized(this) { 
    // method body 
} 
0

यह सच है और यह इस तरह से करता है घेर लिया। यह आवश्यक है कि उस वस्तु के डेटा को सुसंगत बनाए रखें।

मान लीजिए कि यह सत्यापन वहां नहीं है और एक चर एक्स है जो 2 अलग सिंक्रनाइज़ विधि xxx() और yyy() द्वारा छेड़छाड़ की जा रही है।

ताकि थ्रेड ए को विधि xxx() का तालाब मिल जाए जो x = 5 को जोड़ता है और दूसरा थ्रेड बी विधि yyy() को बंद कर देता है और x = -5 में हेरफेर कर रहा है तो विधि xxx() थ्रेड ए के अंत में एक्स = 5 की उम्मीद है लेकिन यह x = 0 मिलेगा जो गलत है।

यह इस तरह से लागू क्यों किया जाता है।

0

यदि किसी वर्ग में 4 सिंक्रनाइज़ विधियां हैं, तो हाँ एक समय में केवल एक थ्रेड के पास उन तरीकों तक पहुंच होगी। मुझे लगता है कि यहां संदेह था, प्रत्येक थ्रेड एकल वर्ग उदाहरण के लिए एक समय में diff सिंक्रनाइज़ विधियों तक पहुंच सकता है। जवाब न है। केवल एक धागा एक समय में सिंक्रनाइज़ किए गए तरीकों तक पहुंच सकता है।

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