2009-04-30 18 views
10

मैं अपने जावा गुइ में एक रेस हालत से निपट रहा हूं, मुझे विश्वास है।जावा अज्ञात वर्ग और सिंक्रनाइज़ेशन और "यह"

synchronized foo() 
{ 
    someMethod(new TimerTask() 
    { 
      public synchronized run() 
      { 

       //stuff 

      } 
    }; 
} 

प्रश्न:: कि रन TimerTask वस्तु या वर्ग कि foo में है पर सिंक्रनाइज़ विधि है

मैं कुछ तरीकों कि एक "गुमनाम विधि" एक अनाम वर्ग के भीतर इस प्रकार बना है?

प्रश्न 2: यदि मैं रन() घोषणा में "सिंक्रनाइज़" से छुटकारा पाता हूं, और इसके बजाय रन() शरीर के अंदर एक सिंक्रनाइज़ (यह) {} ब्लॉक है, तो यह "टाइमरटास्क ऑब्जेक्ट" उस ऑब्जेक्ट पर जो विधि का उदाहरण है जिसमें foo() है?

कृपया यहां मेरी सहायता करें।

धन्यवाद, jbu

+0

यह एक गलती है जो जावा कंसुरेंसी इन प्रैक्टिस (जेसीआईपी) पुस्तक में भी दिखाई देती है। यह एक दयालुता जावा है जो सिंक्रनाइज़ के संबंध में इतनी कमजोर टाइप की गई है। –

उत्तर

13

run विधि TimerTask पर सिंक्रनाइज़ किया गया है। सिंक्रनाइज़ instance methods are always synchronized on this ऑब्जेक्ट। (कक्षा तरीकों Class वस्तु पर सिंक्रनाइज़ किए जाते हैं।)

आप जिस वस्तु की foo एक सदस्य है पर सिंक्रनाइज़ करने के लिए चाहते हैं, आप qualify the this keyword. मान लीजिए foo() की जरूरत है, Bar वर्ग का एक सदस्य है TimerTask की run() विधि के अंदर , आप

public void run() { 
    synchronized(Bar.this) { 
    ... 
    } 
} 
+0

"सिंक्रनाइज़ किए गए तरीकों को हमेशा इस ऑब्जेक्ट पर सिंक्रनाइज़ किया जाता है।" - इस मामले में यह ऑब्जेक्ट यह अंतर करना मुश्किल है। क्या यह हमेशा सबसे निचला/निकटतम वर्ग है? – jbu

+0

हां, मुझे लगता है कि आप इसे इस तरह से रख सकते हैं। यह वह उदाहरण है जिसकी विधि एक सदस्य है। रन() अज्ञात टाइमरटास्क का सदस्य है; foo() संलग्न उदाहरण का सदस्य है। – erickson

+0

अगर हमारे पास बीजीजीए बंद हो तो यह और अधिक मजेदार होगा। यह पारंपरिक (सीमित) बंदियों में भीतरी कक्षा को संदर्भित करेगा, लेकिन बीजीजीए (अधिक पूर्ण) बंद में बाहरी वर्ग। –

2

मैं इन उत्तरों की यकीन है कि हूँ, लेकिन मैं एक अच्छा स्रोत एटीएम की खुदाई नहीं कर सकते।

पहला प्रश्न:
सिंक्रनाइज़ किया गया टाइमरटास्क पर लॉक होगा।

दूसरा प्रश्न:
यह टाइमरटास्क को संदर्भित करता है; यदि आप उस ऑब्जेक्ट को लॉक करना चाहते हैं तो आप MyContainingObject.this

1

केवल एक थ्रेड है जो स्विंग तत्वों तक पहुंच प्राप्त कर सकता है। AWT-EventQueue-0 Thats। आपको इसके बारे में पता होना चाहिए। यदि आपके अन्य धागे तत्वों को बह रहे हैं या बदल रहे हैं तो बहुत अच्छी संभावना है कि गुई दुर्घटनाग्रस्त हो जाएगी। इस सूत्र के साथ अपने जीयूआई चलाने के लिए:

 
    try { 
      SwingUtilities.invokeAndWait(new Runnable(){ 
       public void run(){ 
        Swing_Prozor1 prozor = new Swing_Prozor1(); 
       } 
      }); 
     } catch (InterruptedException e) { 
      //namjerno zanemareno 
     } catch (InvocationTargetException e) { 
      //namjerno zanemareno 
     } 

और यदि आप Anonymus श्रेणियां होती हैं यह आप वर्ग है जिसमें आप कर रहे हैं के उदाहरण दे देंगे, इसलिए यदि आप Anonymus वर्ग इस में writteing कर रहे हैं। उस वर्ग का उदाहरण है।

ClassName.this

हम्म यह ऊपर कोड आप ने लिखा मुझे इस बताता है: वर्ग के उदाहरण के लिए आप लिखना चाहते हैं। आपने दो बार कोड का हिस्सा पूर्व निर्धारित किया है। जब आप सिंक्रोननाइज्ड विधि लिखते हैं तो इसका मतलब है कि केवल एक थ्रेड एक ही समय में इस विधि तक पहुंच सकता है। अन्य धागे इंतजार करते हैं जबकि सिंक्रोनिज्ड विधि अनलॉक होती है।

0

आप देख रहे हैं foo() और रन (सिंक्रनाइज़ करने के लिए) तो आप

की तरह एक स्पष्ट ताला वस्तु

अंतिम वस्तु ताला = नई वस्तु बना सकते हैं();

और फिर उस पर सिंक्रनाइज़ करें।

foo() { 
    synchronized(lock) { 
     someMethod(new TimerTask() { 
      public void run() { 
       synchronized(lock) { 
        //stuff 
       } 
      } 
     } 
संबंधित मुद्दे