प्रतीक्षा को निष्पादित करने के बाद (), यदि कोई धागा अन्य थ्रेड से अधिसूचित नहीं होता है तो कब तक प्रतीक्षा करता है?

Aug 16 2020

नीचे दिए गए उदाहरण में, चूंकि मुख्य-सूत्र को बाल धागे से अधिसूचित नहीं किया जा रहा है, इसलिए इसे हमेशा इंतजार करना चाहिए। लेकिन मुख्य-सूत्र निष्पादित हो रहा है और निम्न उदाहरण का आउटपुट है:

c
l
total: 19900

मुख्य-सूत्र को क्यों निष्पादित किया जा रहा है?

public class ThreadX extends Thread {
    static int total = 0;

    public void run() {
        synchronized (this) {
            for (int i = 0; i < 200; i++) {
                total = total + i;
            }
            System.out.println("c");

        }
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadX t = new ThreadX();

        t.start();
        synchronized (t) {
            t.wait();
            System.out.println("l");
        }

        System.out.println("total: " + total);

    }
}

जवाब

10 akuzminykh Aug 16 2020 at 09:58

प्रश्न-शरीर का उत्तर

देखें Thread#join(long):

[...] जैसा कि एक थ्रेड समाप्त होता है this.notifyAllविधि लागू होती है। [...]

ध्यान दें कि Thread#join()उस फ़ंक्शन को कॉल करता है 0, जिसका अर्थ है हमेशा के लिए।

[...] ० का समय समाप्त होने का अर्थ है हमेशा के लिए प्रतीक्षा करना।

तो आपके मामले में यहाँ tबस कॉल करता है notifyAllजब यह समाप्त हो जाता है, जो उस मुख्य-सूत्र को सूचित करता है जो प्रतीक्षा कर रहा है t


यह अनपेक्षित व्यवहार यही कारण है कि वे प्रलेखन में निम्नलिखित लिखते हैं:

यह अनुशंसित है कि आवेदन पत्र का उपयोग नहीं wait, notifyया notifyAllपर Threadउदाहरणों।

प्रश्न-शीर्षक का उत्तर दें

देखें Object#wait(या JLS (17.2.1। प्रतीक्षा करें) ):

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

तो जावा में थ्रेड्स किसी भी समय जाग सकते हैं। एक स्पुरियस वेकअप बहुत संभावना नहीं है लेकिन यह हो सकता है।