क्यों एक InterruptException ब्लॉक में Thread.currentThread.interrupt () को इनवोक करें?


जवाबों:


160

यह राज्य रखने के लिए किया जाता है

जब तुम पकड़ते हो InterruptException इसे और इसे निगलते हैं, तो आप अनिवार्य रूप से किसी भी उच्च स्तर के तरीकों / थ्रेड समूहों को बीच में रोकने से रोकते हैं। जिसके कारण समस्या हो सकती है।

कॉल करने से Thread.currentThread().interrupt(), आप थ्रेड के इंटरप्ट फ़्लैग को सेट करते हैं, इसलिए उच्च स्तरीय इंटरप्ट हैंडलर इस पर ध्यान देंगे और इसे उचित तरीके से संभाल सकते हैं।

व्यवहार में जावा कॉन्सैरेसी इस पर अधिक विस्तार से चर्चा करता है अध्याय 7.1.3 : व्यवधान का जवाब । इसका नियम है:

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


15
में प्रलेखन यह कहा जाता है कि "परंपरा के मुताबिक, कोई भी तरीका है कि एक फेंक कर बाहर निकलता InterruptedException साफ करता है स्थिति को बीच में जब यह ऐसा नहीं करता है। मुझे लगता है कि इस के संदर्भ में इस सवाल का जवाब स्पष्ट करता है क्यों आप बाधा स्थिति को बनाए रखने की जरूरत है।
Stelios Adamantidis

यह भी ध्यान देने योग्य है कि interrupt()कॉल बाधित ध्वज को सेट करने का एकमात्र तरीका है जब आप इस राज्य के बारे में अन्य "वितरण तंत्र" के माध्यम से अधिसूचना प्राप्त करते हैं - InterruptedExceptionऔर इच्छा या इसे फिर से फेंक नहीं सकते।
sevo

67

मुझे लगता है कि यह कोड नमूना चीजों को थोड़ा स्पष्ट करता है। जो वर्ग काम करता है:

   public class InterruptedSleepingThread extends Thread {

        @Override
        public void run() {
            doAPseudoHeavyWeightJob();
        }

        private void doAPseudoHeavyWeightJob() {
            for (int i=0;i<Integer.MAX_VALUE;i++) {
                //You are kidding me
                System.out.println(i + " " + i*2);
                //Let me sleep <evil grin>
                if(Thread.currentThread().isInterrupted()) {
                    System.out.println("Thread interrupted\n Exiting...");
                    break;
                }else {
                    sleepBabySleep();
                }
            }
        }

        /**
         *
         */
        protected void sleepBabySleep() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                //e.printStackTrace();
                Thread.currentThread().interrupt();
            }
        }
    }

मुख्य वर्ग:

   public class InterruptedSleepingThreadMain {

        /**
         * @param args
         * @throws InterruptedException
         */
        public static void main(String[] args) throws InterruptedException {
            InterruptedSleepingThread thread = new InterruptedSleepingThread();
            thread.start();
            //Giving 10 seconds to finish the job.
            Thread.sleep(10000);
            //Let me interrupt
            thread.interrupt();
        }

    }

स्टेटस वापस सेट किए बिना कॉलिंग इंटरप्ट की कोशिश करें।


13
तो निष्कर्ष क्या है ??
स्कॉट 混合

3
धन्यवाद। मैं देख रहा हूं कि अब आपका क्या मतलब है: repl.it/@djangofan/InterruptedThreadExample
djangofan

20

ध्यान दें:

http://download.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html

मैं एक थ्रेड को कैसे रोक सकता हूं जो लंबे समय तक प्रतीक्षा करता है (जैसे, इनपुट के लिए)?

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

Thread.currentThread().interrupt();

यह सुनिश्चित करता है कि थ्रेड इंटरप्टेड एक्ससेप्शन को जैसे ही सक्षम होगा, उसे फिर से जीवित करेगा।


2

मैं इसे एक बुरा अभ्यास या कम से कम थोड़ा जोखिम भरा समझूंगा। आमतौर पर उच्च स्तर की विधियां अवरुद्ध संचालन नहीं करती हैं और वे कभी नहीं देखेंगेInterruptedException वहां । यदि आप इसे हर उस जगह पर मास्क लगाते हैं, जहां आप रुकावट ऑपरेशन करते हैं, तो आपको यह कभी नहीं मिलेगा।

Thread.currentThread.interrupt()किसी भी अन्य अपवाद या किसी अन्य तरीके से सिग्नलिंग बाधा अनुरोध को बढ़ाने या न करने का एकमात्र तर्क (जैसे interruptedकिसी थ्रेड के मुख्य लूप में स्थानीय चर चर सेट करना ) वह स्थिति है जहां आप वास्तव में अपवादों के साथ कुछ भी नहीं कर सकते हैं, जैसे finallyब्लॉकों में।

यदि आप Thread.currentThread.interrupt()कॉल के निहितार्थ को बेहतर ढंग से समझना चाहते हैं, तो Péter Török का जवाब देखें ।


0

जावा डॉक से देखें

यदि यह धागा प्रतीक्षा (), ज्वाइन (), स्लीप (लंबा) के एक आह्वान में अवरुद्ध है, तो इसकी रुकावट की स्थिति को साफ कर दिया जाएगा और इसे इंटरप्टेड अपवाद प्राप्त होगा।

यदि यह थ्रेड I / O ऑपरेशन में अवरुद्ध है, तो थ्रेड की व्यवधान स्थिति सेट हो जाएगी, और थ्रेड एक ClosedByInterruptException प्राप्त करेगा।

यदि यह थ्रेड एक चयनकर्ता में अवरुद्ध है, तो थ्रेड की रुकावट स्थिति सेट की जाएगी और यह चयन ऑपरेशन से तुरंत वापस आ जाएगी।

यदि पिछली कोई भी शर्त नहीं है, तो इस थ्रेड की रुकावट की स्थिति निर्धारित की जाएगी।

इसलिए, यदि आप @Ajay जार्ज उत्तर में I / O ऑपरेशन या सिर्फ एक साइनआउट में sleepBabySleep () विधि बदलते हैं, तो आपको प्रोग्राम को रोकने के लिए स्थिति वापस सेट करने की आवश्यकता नहीं है। (BTW, वे भी InterruptedException फेंक नहीं)

जैसे @ Péter Török ने कहा => यह राज्य रखने के लिए किया जाता है। (और विशेष रूप से उस विधि के लिए जो रुकावट फेंक देगी)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.