2012-10-09 17 views
7

कॉल करने योग्य में Thread.interrupted() को संभालने का उचित तरीका क्या है? मुझे लगता है कि कॉल करने योग्य को एक इंटरप्टेड अपवाद फेंकना चाहिए; उदाहरण के लिए:कॉल करने योग्य में Thread.interrupted() को संभालने का सही तरीका?

public class MyCallable implements Callable<Object> { 
    public Object call() { 
     Object result = null; 

     // Simulate long-running operation that calculates result 
     while (true) { 
      ... 
      if (Thread.interrupted()) { 
       throw new InterruptedException(); 
      } 
     } 

     result = ... // something produced by the long-running operation  

     return result; 
    } 
} 

क्या यह सही है, या इसे संभालने का एक और उचित तरीका है? धन्यवाद।

+3

'इंटरप्टेड एक्सेप्शन' को समझाने के लिए एक सही स्रोत है [यहां] (http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html)। –

+0

मैंने इसे पहले पढ़ा था, लेकिन इसमें कॉल करने योग्य का उल्लेख नहीं है। हालांकि, बहुत अच्छा लेख है। –

उत्तर

6

संपादित:

कुछ वापस करने के बाद आगे और पीछे, ऐसा लगता है जैसे आप अपने आईओ दिनचर्या बाधित करने के लिए सक्षम होना चाहते हैं। यह कुछ एनआईओ InterrutibleChannel कक्षाओं के लिए एक अच्छी नौकरी की तरह लगता है। उदाहरण के लिए, निम्नलिखित BufferedReader से पढ़ना बाधित है और InterruptedIOException फेंक देगा। more examples of the NIO code के लिए यहां देखें।

BufferedReader in = new BufferedReader(new InputStreamReader(
    Channels.newInputStream((new FileInputStream(
     new File(...))).getChannel()))); 

उसके बाद, आप future.cancel() जो अपने धागा बाधित हो जाएंगी कॉल और आईओ एक InterruptedIOException फेंकने के लिए हो सकता है। यदि ऐसा होता है, तो आप IOException को पकड़ सकते हैं और इसे call() विधि से बाहर निकलने दें।


आप Future कि call() विधि बाधित किया गया था तो मैं फेंकने लगता है कि InterruptedException ठीक है वापस करने के लिए पास करना चाहते हैं। एक और विकल्प केवल return null; या आपके call() विधि से कुछ अन्य मार्कर ऑब्जेक्ट होगा। अगर आम तौर पर धागा बाधित होता है तो मैं आमतौर पर ऐसा करता हूं।

एक बात याद रखना महत्वपूर्ण है कि अगर call() फेंकता InterruptedException, जब आप एक future.get() कर फेंक होगा एक ExecutionException और कारण कि अपवाद का एक InterruptedException होने जा रहा है है। भ्रमित न हों कि future.get()get(long timeout, TimeUnit unit) बार बाहर होने पर InterruptedException भी फेंक सकता है।

try { 
    result = future.get(); 
} catch (ExecutionException e) { 
    if (e.getCause() instanceof InterruptedException) { 
     // call() method was interrupted 
    } 
} catch (InterruptedException e) { 
    // get was interrupted 
} 

अगर, हालांकि, future.cancel(true) तो कहा जाता था future.get() एक CancellationException बजाय फेंक देते हैं।

+0

मैं थोड़ा और संदर्भ प्रदान करूंगा। मेरा कोड वास्तव में थोड़ी देर (सत्य) लूप का उपयोग नहीं करता है - यह एक कस्टम इनपुटस्ट्रीम से पढ़ रहा है जो पढ़ने (बाइट) में Thread.interrupted() के मान की जांच करता है। पढ़ने() विधि इंटरप्टेड एक्सेप्शन को यह सुनिश्चित करने के लिए फेंकता है कि कॉलिंग कोड (जो स्ट्रीम से पढ़ रहा है) ठीक से स्ट्रीम को बंद कर देता है। –

+0

यह पता चला है कि यह काम नहीं करेगा, क्योंकि पढ़ा जा सकता है() केवल IOException फेंक सकता है। ऐसा लगता है कि मैं क्या चाहता हूं interruptedIOException हो सकता है। –

+0

ज़रूर @ ग्रेग। एक अन्य विचार एनआईओ का समर्थन करने वाले 'इंटरप्टिबल चैनल' का उपयोग करना है। – Gray

1

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

try{ 
    future.get(); 
}catch(ExecutionException ex){ 

}catch(InterruptedException em){ 

} 

throw new InterruptedException

नहीं चाहता किसी भी अपवाद तब होता है यदि आप इसे होने की उम्मीद करेंगे? आपके मामले में यह ExecutionException है। यदि आप ExecutionException नहीं चाहते हैं तो आपको इंटरप्टेड अपवाद को पुनर्स्थापित नहीं करना चाहिए।

+0

इस मामले में, मेरा कॉल करने योग्य इनपुट इनपुट से पढ़ रहा है। मैं यह सुनिश्चित करना चाहता हूं कि अगर स्ट्रीम() को भविष्य के उदाहरण पर कॉल किया जाता है तो स्ट्रीम बंद हो जाती है (ग्रे के उत्तर पर मेरी टिप्पणी देखें)। –

+0

क्या आप कभी भविष्य में 'प्राप्त' करते हैं? –

+0

हां, आखिरकार मैं भविष्य में() भविष्य को रद्द नहीं करूँगा (अगर भविष्य रद्द नहीं हुआ था)। –

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