2011-02-05 9 views

उत्तर

110

यह पर किया गया है रखें।

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

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

Java Concurrency in Practiceअध्याय 7.1.3 में अधिक विस्तार से इसकी चर्चा करता है: में बाधा का जवाब देना। इसका नियम है:

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

+7

[प्रलेखन] में (https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html) यह कहा गया है कि _ "सम्मेलन द्वारा, कोई भी विधि जो 'इंटरप्टेड एक्सेप्शन' फेंकने से निकलती है ** इंटरप्ट स्थिति को साफ़ करता है ** जब ऐसा होता है ._ मुझे लगता है कि यह उत्तर को स्पष्ट करता है _why_ आपको इंटरप्ट स्थिति को संरक्षित करने की आवश्यकता है। –

2

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

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

पेटर टोरोक का जवाब देखें, अगर आप Thread.currentThread.interrupt() कॉल के प्रभाव को बेहतर ढंग से समझना चाहते हैं।

14

नोट:

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

मैं कैसे (इनपुट के लिए, उदाहरण के लिए) एक धागा है कि लंबी अवधि के लिए इंतजार कर रहा है रोक सकता हूं?

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

Thread.currentThread().interrupt(); 

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

45

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

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(); 
     } 

    } 

स्थिति को वापस स्थापित करने के बिना बाधा कॉल करके देखें।

+5

बहुत बढ़िया उदाहरण, धन्यवाद। – Ben

+4

तो निष्कर्ष है ?? –

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