2009-05-06 15 views
5

जब आप सूचित करते हैं तो क्या होता है किसी ऑब्जेक्ट पर सभी विधि जो प्रतीक्षा नहीं कर रही हैं? क्या अपवाद होना चाहिए या क्या यह सामान्य स्थिति है?जावा - प्रतीक्षा करें और सूचित करें सभी

उत्तर

6

यह पूरी तरह से सामान्य है। आप केवल एक ही मॉनिटर पर प्रतीक्षा करने वाले सभी को सूचित कर सकते हैं। हर कोई दिलचस्पी नहीं है। जिस ऑब्जेक्ट पर आप सूचित करते हैं वह सब केवल मॉनीटर है जिस पर अन्य प्रतीक्षा कर रहे हैं। कोई भी कोई भी इंतज़ार कर रहा है तो आप यहां देख सकते हैं, बुला notifyAll() एक प्रतीक्षा नहीं वस्तु पर कोई असर नहीं है

8

अधिसूचित किया जाना है।

alt text

+0

यह सख्ती या चेतावनी है कि पहली बात यह है एक अधिसूचित धागा करता है पर नजर रखने के ताला regrab है बिना notifyAll पर चल रहा है कम से कम नहीं करने के लिए इंतजार कर से एक धागा डालने के लिए सही नहीं हो सकता है। और चूंकि अधिसूचित धागे की संख्या में से केवल एक ही इसे पकड़ सकता है, अन्य को अवरुद्ध कर दिया जाएगा। लेकिन अवरोधन प्रतीक्षा के समान नहीं है क्योंकि अवरुद्ध धागे को अन्य अधिसूचना() सिग्नल की आवश्यकता नहीं है। –

1

केवल इंतजार कर वस्तुओं सूचित किया जाए। ऑब्जेक्ट.वाइट() एक टाइमआउट या अधिसूचना तक ब्लॉक करता है - तो सवाल यह बनी हुई है कि आप क्यों सोचते हैं या क्यों नहीं प्रतीक्षा ऑब्जेक्ट्स को अधिसूचित किया जाएगा? इसका कोई मतलब नही बनता।

+0

ऑब्जेक्ट्स प्रतीक्षा या अधिसूचित नहीं हैं - धागे करते हैं। और यह मॉनिटर ऑब्जेक्ट पर सूचित करने के लिए पूरी तरह से संभव और सामान्य है, बिना यह जानने के कि क्या थ्रेड प्रतीक्षा कर रहे हैं या नहीं। उदाहरण के लिए, एक कतार के साथ एक निर्माता/उपभोक्ता परिदृश्य में, उपभोक्ता ने कतार खाली कर दी हो और फिर भी प्रसंस्करण के साथ कब्जा कर लिया जाए जब निर्माता कतार में एक नया तत्व जोड़ता है और इस बारे में सभी उपभोक्ताओं को सूचित करता है (यानी कोई नहीं)। –

+0

मैंने चीजों को यथासंभव सरल रखने के लिए थ्रेड को हटा दिया। –

2

वस्तु "पर इंतजार कर रहे थे" है, जो अपने आप इंतजार कर नहीं। धागा वह है जो प्रतीक्षा कर रहा है। अगर कोई इंतजार नहीं कर रहा है, तो कोई भी जाग जाएगा और कुछ विशेष नहीं होगा।

+0

अलार्म बंद होने पर क्या होता है लेकिन इसे सुनने के लिए कोई नहीं है? –

2

पूरी तरह से सामान्य स्थिति।

मान लें कि आप एक निर्माता धागा इसे में तत्वों और एक उपभोक्ता धागे से तत्वों को हटाने डालने के साथ एक कतार है।

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

1

मैं केवल बंटवारे बाल ;-) यह सख्ती धागे notifyAll पर राज्य 'चल' के लिए राज्य 'इंतज़ार कर' से रखा जा रहा है के बारे में सोच करने के लिए सही नहीं हो सकता है हो सकता है; कम से कम चेतावनी के बिना नहीं कि पहली चीज एक अधिसूचित धागा मॉनिटर लॉक को वापस लेता है। और चूंकि अधिसूचित धागे की संख्या में से केवल एक ही इसे पकड़ सकता है, अन्य अवरुद्ध होंगे। अवरोधित (Thread.State.Blocked) धागा राज्य है। लेकिन अवरुद्ध की प्रतीक्षा के समान नहीं है क्योंकि अवरुद्ध थ्रेड को फिर से शुरू करने के लिए अन्य अधिसूचना() सिग्नल की आवश्यकता नहीं है। [वैसे मैं नकली जागने के बारे में जानता हूं लेकिन शायद कुछ जेवीएम कार्यान्वयन के लिए विपरीत भी सच हो सकता है - एक याद आती है?]

public class HellBoy { 
    public static class MyThread extends Thread { 
     static final public Object sharedLock = new Object(); 

     public void run() { 
      synchronized (sharedLock) { 
       System.out.println("Gonna wait..."); 
       try { 
        sharedLock.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       System.out.println("Woken up but sleeping with the lock"); 
       try { 
        Thread.sleep(2500); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       System.out.println("exiting and unlocking"); 
      } 
     } 
    } 

    public static void main(String[] args) throws Exception { 
     new MyThread().start(); 
     new MyThread().start(); 
     new MyThread().start(); 
     new MyThread().start(); 
     Thread.sleep(200); 
     synchronized (MyThread.sharedLock) { 
      MyThread.sharedLock.notifyAll(); 
     } 
    } 
} 
+0

क्या एक अधिसूचना याद किया जा सकता है? –

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