मेरे पास 4 धागे हैं प्रत्येक एक अलग विधि निष्पादित कर रहा है, मैं इच्छा आउटपुट खींचने में सक्षम हूं हालांकि धागे समाप्त नहीं हो रहे हैं या नौकरी समाप्त होने पर लूप से बाहर निकलने में सक्षम नहीं हैं।

क्या कोई आपकी राय से मेरी मदद कर सकता है।

मुझे लगता है कि प्रत्येक धागा प्रतीक्षा कथन पर अटक गया है और किसी से इसे संकेत देने की अपेक्षा कर रहा है। मैंने कार्य पूरा होने के बाद सभी धागे को स्पष्ट रूप से संकेत देने का प्रयास किया लेकिन कोई भाग्य नहीं।

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

    private int n;
    Lock lock = new ReentrantLock();
    Condition executeFizz;
    Condition executeBuzz;
    Condition executeFizzBuzz;
    Condition executeNumber;
    volatile private boolean flag;   

    public FizzyBuzz(int n) {
        this.n = n;
        this.executeFizz = lock.newCondition();
        this.executeBuzz = lock.newCondition();
        this.executeFizzBuzz = lock.newCondition();
        this.executeNumber = lock.newCondition();
        this.flag = true;
    }

    public  void fizz()   {
        lock.lock();
        while(true) {
        try {           
            executeFizz.await();
            if(!flag) break;
        } catch (InterruptedException e) {
        }
        System.out.println("fizz");
        executeNumber.signal();
        }

    }

    public void buzz()  {
        lock.lock();
        while(true) {
        try {
            executeBuzz.await();
            if(!flag) break;
        } catch (InterruptedException e) {
        }
        System.out.println("buzz");
        executeNumber.signal();

        }

    }

    public void fizzbuzz()   {
        lock.lock();
        while(true) {
        try {
            executeFizzBuzz.await();
            if(!flag) break;
        } catch (InterruptedException e) {
        }
        System.out.println("fizzbuzz");
        executeNumber.signal();
        }

    }

    public  void number() throws InterruptedException  {
        lock.lock();
        for(int i=1;i<=n;i++)
        {       
            if(i%3==0&&i%5==0)
                {
                    executeFizzBuzz.signal();
                    executeNumber.await();
                }
            else if(i%3==0)
                {

                    executeFizz.signal();
                    executeNumber.await();
                }
                else if(i%5==0)
                {
                    executeBuzz.signal();
                    executeNumber.await();
                }
                else
                {
                    System.out.println(i);
                }   
        }
        flag = false;
        executeFizzBuzz.signal();
        executeFizz.signal();
        executeBuzz.signal();

0
Shelly 15 अप्रैल 2020, 15:19

1 उत्तर

सबसे बढ़िया उत्तर

शायद यह वह नहीं करता जो आप सोच रहे थे यह करता है:

while (flag) {
    ...
}

जब भी flag असत्य होगा, वह लूप समाप्त नहीं होगा। यह तब समाप्त हो जाता है जब यह परीक्षण flag करता है और इसे गलत पाता है। यह हर बार लूप के आसपास केवल एक बार होता है। आप इसके बजाय लूप को इस तरह लिख सकते हैं, और यह बिल्कुल उसी तरह व्यवहार करेगा:

while (true) {
    if (! flag) break;
    ...
}

तो अगर आपके पास यह है,

while (flag) {
    ...executeFizz.await()...
}

और यदि flag, await() कॉल में थ्रेड के फंसने के दौरान सत्य से असत्य में बदल जाता है, तो लूप तब तक समाप्त नहीं होगा जब तक await() कॉल के बाद रिटर्न...

...आपके उदाहरण में ऐसा कभी नहीं होगा क्योंकि for लूप के n तक गिने जाने के बाद, यह flag=false; सेट करता है लेकिन यह किसी भी संकेत को नहीं करता है अन्य प्रतीक्षा धागे।


@SolomonSlow मैंने सभी 3 को सिग्नल करने की कोशिश की, लेकिन अगर स्थिति जोड़ने के बाद कोई भाग्य नहीं है, तो कोड के अंत में मैंने यह कोड शामिल किया है ...

मेरा अनुमान है, ऐसा इसलिए है क्योंकि आपके प्रोग्राम में कहीं भी lock.unlock() पर कोई कॉल नहीं है। यहाँ शायद क्या होता है:

  1. तीन "कार्यकर्ता" थ्रेड सभी executeXxxxx.await() पर कॉल कर रहे हैं (प्रत्येक अपने स्वयं के कंडीशन वेरिएबल की प्रतीक्षा कर रहा है।)

  2. "मुख्य" धागा लूप के अंत तक पहुंचता है (यह वर्तमान में lock का मालिक है) और यह प्रत्येक executeXxxxxx कंडीशन वेरिएबल को सिग्नल करता है।

  3. "मुख्य" धागा समाप्त होता है, लेकिन lock अभी भी बंद है। तीनों "वर्कर" थ्रेड्स को अब उनकी संबंधित शर्तों की प्रतीक्षा से मुक्त कर दिया गया है, लेकिन लॉक उपलब्ध होने तक उनकी await() कॉल वापस नहीं आ सकती हैं।

  4. लॉक कभी भी उपलब्ध नहीं होगा क्योंकि ऐसा कोई थ्रेड नहीं है जो इसे अनलॉक कर सके।

समाप्त होने से पहले आपके पास प्रत्येक थ्रेड कॉल lock.unlock() होनी चाहिए।

1
Solomon Slow 15 अप्रैल 2020, 13:41