2010-07-02 8 views
7

मेरे पास निम्न कोड है जिसे मैं सफलतापूर्वक पूरा करने की उम्मीद करता हूं लेकिन कोड "विफल" ("यह नहीं पहुंचा जाना चाहिए") में विफल रहता है; "। कोई व्याख्या कर सकते हैं कृपया क्यों डिफ़ॉल्ट न आया हुआ अपवाद हैंडलर नहीं बुलाया जाता है:जूनिट में बहु-थ्रेड परीक्षण के लिए बिना किसी अपवाद वाले हैंडलर का उपयोग कैसे करें?

public class UncaughtExceptionTest extends TestCase 
    implements UncaughtExceptionHandler { 

    private final List<Throwable> uncaughtExceptions = 
     new CopyOnWriteArrayList<Throwable>(); 

    class UncaughtExceptionTestInnerClass implements Runnable { 
     private final ScheduledThreadPoolExecutor executor = 
      new ScheduledThreadPoolExecutor(1); 
     private final CountDownLatch latch; 

     UncaughtExceptionTestInnerClass(CountDownLatch latch) { 
      this.latch = latch; 
      executor.schedule(this, 50, TimeUnit.MILLISECONDS); 
     } 

     @Override 
     public void run() { 
      System.out.println("This is printed"); 
      fail("this should fail"); 
      latch.countDown(); 
     } 
    } 

    @Test 
    public void testUncaughtExceptions() { 
     Thread.setDefaultUncaughtExceptionHandler(this); 
     CountDownLatch latch = new CountDownLatch(1); 
     UncaughtExceptionTestInnerClass testTheInnerClass = 
       new UncaughtExceptionTestInnerClass(latch); 
     try { 
      if (!latch.await(1, TimeUnit.SECONDS)) { 
       if (uncaughtExceptions.size() > 0) { 
        Throwable exception = uncaughtExceptions.get(0); 
        System.out.println("First uncaught exception: " + 
            exception.getMessage()); 
       } 
       else { 
        fail("this should not be reached"); 
       } 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void uncaughtException(Thread t, Throwable e) { 
     uncaughtExceptions.add(e); 
    } 
} 
+0

'असफल क्यों है (" यह असफल होना चाहिए "); 'वहां लाइन? क्या यह जानबूझकर है? इस तरह लच कभी गिना जाता है। – BalusC

+0

@ बालससी: हाँ, यह जानबूझकर है। परीक्षण को सही तरीके से पास करने के लिए, latch.await() विधि को समय निकालना चाहिए, जिससे यह झूठी वापसी हो सकती है। कोड को तब तक असीमित AssertionFailedError अपवाद से संदेश मुद्रित करना चाहिए जिसे आप पूछ रहे लाइन पर फेंक दिया गया था। –

उत्तर

12

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

आप कार्य सबमिट करने के तरीके के आधार पर, निष्पादक धागा सभी थ्रोबल को पकड़ सकता है और उन्हें संभाल सकता है। इसलिए, इन अपवादों के कारण धागा समाप्त नहीं होता है, और इस प्रकार अपरिपक्व अपवाद हैंडलर शामिल नहीं होता है। उदाहरण के लिए, ThreadPoolExecutor.execute (Runnable) बेजोड़ अपवाद हैंडलर को ट्रिगर करेगा। हालांकि, ThreadPoolExecutor.submit (कॉल करने योग्य) नहीं है। इसके अलावा, अनुसूचित थ्रेडपूलएक्ससेटर.schedule() या तो नहीं (इसे कार्यान्वयन के लिए फ़्यूचरटास्क के उपयोग के साथ करना है)।

निष्पादक सेवा के साथ अप्रत्याशित अपवादों तक पहुंचने का एक बेहतर तरीका भविष्य के माध्यम से है।

1

ScheduledThreadPoolExecutor.schedule()Runnable/Callable तर्क लेता है, Thread नहीं। पूर्व में रनटाइम अपवाद हैंडलर नहीं हैं। अपने run या call विधि में try/catchRuntimeException के लिए ब्लॉक करें।

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