2010-05-14 17 views
7

java.lang.Object में दो सूचना विधियां क्यों हैं - notify और notifyAll? ऐसा लगता है कि notifyAll कम से कम सब कुछ notify करता है, तो क्यों न केवल notifyAll का उपयोग क्यों करें? यदि notifyAll का उपयोग notify के बजाय किया जाता है, तो क्या प्रोग्राम अभी भी सही है, और इसके विपरीत? इन दो तरीकों के बीच चुनाव को क्या प्रभावित करता है?जावा - कब सूचित या सूचित करने के लिए सभी?

+0

उस प्रश्न का स्वीकार्य उत्तर एक उत्तर पर संकेत देता है - कि अंतर प्रदर्शन है, थ्रेड को जागृत करना जो अधिसूचना का उपयोग करके कोई वास्तविक काम नहीं कर सकता है, केवल एक प्रदर्शन चिंता है। तो मुझे लगता है कि इस सवाल का जवाब - अधिसूचना सभी हमेशा सही है - बस कलाकार के रूप में नहीं। – mdma

+2

जावा 5 (2004 में) के बाद से, एक नई समवर्ती पुस्तकालय जोड़ा गया है। (यह पुस्तकालय वास्तव में बहुत पुराना है) मेरा सुझाव है कि आप उन वर्गों का उपयोग करें और मैं अधिसूचना या अधिसूचना के उपयोग को हतोत्साहित करूंगा। –

+0

इस प्रश्न का उत्तर यहां StackOverflow पर है: [जावा अधिसूचना() बनाम अधिसूचना सभी()] (https://stackoverflow.com/questions/37026/java-notify-vs-notifyall-all-over-again) । – smountcastle

उत्तर

1

notify के लिए JavaDoc के अनुसार:

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

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

1

दो विशिष्ट उदाहरण।

मान लें कि आपके पास निर्माता थ्रेड और उपभोक्ता धागा है। निर्माता द्वारा उत्पादित प्रत्येक "पैकेट" उपभोक्ता द्वारा उपभोग किया जाना चाहिए। उपभोक्ता कुछ कतार में रखता है और फिर notify() पर कॉल करता है (केवल एक उपभोक्ता को "पैकेट" को संसाधित करने के लिए दिया जाना चाहिए।)

मान लें कि लंबी प्रक्रिया समाप्त होने पर आप अधिसूचना लेना चाहते हैं। आप एक बीप और एक स्क्रीन अपडेट चाहते हैं। बीपिंग-थ्रेड और स्क्रीन-अपडेट-थ्रेड दोनों को सूचित करने के लिए प्रक्रिया notifyAll() निष्पादित करती है।

0

अंतर यह है कि notify() वर्तमान धागे पर केवल एक धागा प्रतीक्षा कर रहा है। अधिकांश निर्माता/उपभोक्ता और प्रतिनिधि-और-प्रतीक्षा अनुप्रयोगों के लिए, यह उपयोग करने का उचित तरीका है। इसके अलावा, अगर मौजूदा धागे पर केवल एक अन्य धागा इंतजार कर रहा है, तो उस प्रतीक्षा थ्रेड से अधिक अधिसूचित करने की आवश्यकता नहीं है।

इसके विपरीत, notifyAll() थंप सभी अन्य धागे वर्तमान धागे पर प्रतीक्षा कर रहे हैं। यह उन परिस्थितियों में अधिक उपयोगी है जहां प्रत्येक (संबंधित) सोने के थ्रेड को कुछ करना चाहिए, जैसे थ्रेड को सूचित करते हुए घातक या उच्च-महत्वपूर्ण घटना के जवाब में।

1
//contribute By E.Thulasiram and Team 
    class AA extends Thread{ 
AA a; 
public void get(AA a){ 
    this.a=a; 
} 
public void run(){ 
    System.out.println("one"); 
    synchronized (a) { 
     try{ 
      a.wait(); 
      System.out.println("one wake up"); 
      this.wait(); 
     }catch(Exception e){ 
      System.out.println(e); 
     } 
    } 
} 
    } 
    class BB extends Thread{ 
AA a; 
public void get(AA a){ 
    this.a=a; 
} 
public void run(){ 
    System.out.println("two"); 
    synchronized (a) { 
     try{ 
      a.wait(); 
      System.out.println("two wake up"); 
     }catch(Exception e){ 
      System.out.println(e); 
     } 
    } 
} 
    } 
    class CC extends Thread{ 
AA a; 
public void get(AA a){ 
    this.a=a; 
} 
public void run(){ 
    synchronized (a) { 
     a.notifyAll(); 
     System.out.println("NotifyAll"); 
    } 
} 
    } 
    class DD{ 
public static void main(String args[]){ 
    AA a=new AA(); 
    BB b=new BB(); 
    CC c=new CC(); 
    a.get(a); 
    a.start(); 
    b.get(a); 
    b.start(); 
    c.get(a); 
    c.start(); 
} 
    } 
संबंधित मुद्दे