2012-10-10 19 views
13

जब अमरूद में Throwables.propagate (ई) का उपयोग कर InterruptedException रों से निपटने के लिए सबसे अच्छा अभ्यास क्या है?अमरूद: Throwables.propagate और InterruptedException

मैं throw Throwables.propagate(e) का उपयोग कर प्यार करता हूँ, विशेष रूप से तरीकों कि फेंक कोई अपवाद नहीं है और जहां अपवाद हैंडलिंग फोन करने वाले की जिम्मेदारी है की जाँच की है। लेकिन यह ऐसा नहीं करता जो मैं इंटरप्टेड एक्सेप्शन के साथ अपेक्षा करता हूं।

मैं तथ्य यह है कि धागा बाधित किया गया था खोने के लिए नहीं करना चाहते हैं, तो मैं जैसी चीजों लेखन अंत:

public void run() { 
    Callable c = ...; 
    try { 
     c.call(); 
    } catch (InterruptedException e) { 
     Thread.currentThread().interrupt(); 
     throw Throwables.propagate(e); 
    } catch (Exception e) { 
     throw Throwables.propagate(e); 
    } 
} 

वहाँ अमरूद में ऐसा करने का कोई तरीका है? क्या Throwables.propagate() जैसे कुछ का उपयोग करने के लिए एक (पिछड़ा संगत ?!) तरीका है जो थ्रेड को बाधित करता है, अगर यह एक अवरुद्ध अपवाद को लपेट रहा है और प्रसारित कर रहा है?

+1

मैं इसे गुवा – artbristol

उत्तर

7

सुविधाजनक रूप से, हमने कुछ समय पहले इस पर चर्चा की थी। मैं तो बस कॉपी कर देंगे और पेस्ट:

Throwables.propagate(e) पर मेरे हार्ड लाइन की राय है कि यह मूल रूप से throw new RuntimeException(e) है और लोगों को आमतौर पर ऐसा नहीं होना चाहिए कि, बस के रूप में वे आम तौर पर throw new RuntimeException(e) नहीं लिखना चाहिए। (और यदि वे इसे लिखने जा रहे हैं, तो वे इसे सीधे लिख सकते हैं ताकि यह स्पष्ट हो कि क्या हो रहा है।)

catch (Exception e) पर मेरी हार्ड-लाइन राय - आमतौर पर लोग इस गड़बड़ी में कैसे आते हैं - यह है कि वे आमतौर पर ऐसा नहीं करना चाहिए, या तो। (जाहिर है जिन मामलों में catch (Exception e) स्पष्ट रूप से मूल रूप से किसी उच्च-स्तरीय, आपरेशन-गुंजाइश कैच ब्लॉक करना सही बात() है हैं, लेकिन उन रहे हैं ... स्पष्ट।)

InterruptedException पर मेरे हार्ड लाइन राय है कि InterruptedExceptionException लागू करने के लिए बिल्कुल इस तरह से टूटा हुआ है: इसे विशेष हैंडलिंग की आवश्यकता है कि अन्य अपवाद नहीं हैं।

InterruptedException को RuntimeException में कनवर्ट करने पर मेरी हार्ड-लाइन राय "नहीं है।" (यह, मैंने उपर्युक्त अन्य सामानों की तरह विवादास्पद है।)

तो एक तरफ, मुझे यकीन नहीं है कि हम propagate() बचाने के लिए कुछ भी कर सकते हैं। दूसरी ओर, शायद विधि को थोड़ा कम बुरा बनाना अच्छा लगता है।

फिर

फिर, इस फोन करने वाले है, जो पकड़ता पर विचार ExecutionException e:

throw Throwables.propagate(e.getCause());

यह उपभोक्ता धागा बाधित करने के लिए, बस के रूप में यह सीधे e.getCause() फेंकने के लिए गलत होगा गलत होगा क्योंकि रुकावट इरादा था कंप्यूटिंग थ्रेड के लिए, उपभोक्ता धागा नहीं।

मैं propagate() अकेला छोड़ने के लिए इच्छुक हूँ। (जैसा कि आप शायद अनुमान लगा सकते हैं, मैं व्यक्तिगत रूप से इसे कम करने के इच्छुक हूं, लेकिन यह एक बड़ी चर्चा है।)

+1

+1 दिलचस्प बिंदुओं के भीतर एक सुविधा अनुरोध के रूप में उठाऊंगा। मुझे आश्चर्य है कि लोग 'थ्रोएबल्स.प्रोपैगेट फेंकते हैं (e.getCause()); '! स्टैक ट्रेस एक थ्रेड में सब कुछ हुआ जैसा दिखता है! – artbristol

+1

धन्यवाद, दिलचस्प अंक। इंटरप्ट किए गए अपवाद को +1 अपवाद को गलत करने के लिए लागू किया गया है, लेकिन जावा वह जगह है जहां यह है। मुझे लगता है कि InterruptedException को एक रनटाइम अपवाद में परिवर्तित करना कभी-कभी आवश्यक होता है: यदि मेरा विधि हस्ताक्षर बाहरी इंटरफ़ेस द्वारा तय किया जाता है (इसलिए मैं इंटरप्टेड एक्सेप्शन फेंक नहीं सकता), और मेरा ऑपरेशन बाधित था (इसलिए मैं अपना अनुबंध पूरा नहीं कर सकता), I एक अपवाद फेंकना चाहिए। धागे को बाधित करने और RuntimeException फेंकने के अलावा अन्य समझदार विकल्प क्या है? –

+4

'फेंकने के लिए नया रनटाइम अपवाद (ई)' लिखने के लिए, अपवादजनक शोर अपवाद को अपवाद लपेटने के लिए है (विशेष रूप से जब यह कुछ भी उपयोगी नहीं जोड़ रहा है, जैसे वर्तमान संदर्भ के बारे में एक अतिरिक्त संदेश)। जहां भी शोर से बचा जा सकता है (उदाहरण के लिए यह पहले से ही एक अनचेक अपवाद है) तो महान। इस बात का एक स्कूल है कि एपीआई को जहां भी संभव हो अनचेक अपवादों का उपयोग करना चाहिए। भले ही कोई उस तर्क को नहीं खरीदता है, फिर भी किसी को भी इस तरह से लिखे गए अन्य लोगों के इंटरफेस को लागू करना होगा। तो कृपया 'Throwables.propagate (e)' को बहिष्कृत न करें! –

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