2015-07-14 29 views
10

के साथ थ्रेड मुझे लाइन 42 और 43: Thread t1=new Thread(()->prod.test());, Thread t2=new Thread(()->cons.test());अनचाहे अपवाद प्रकार इंटरप्टेड एक्सेप्शन पर कोई त्रुटि है। यदि मैं क्विकफ़िक्स करने का प्रयास करता हूं तो यह कैच अपवाद के साथ पकड़ने का प्रयास करेगा, इसमें एक ही त्रुटि होगी और इसे उसी तरह से ठीक करने की कोशिश की जाएगी जिससे इसे पकड़ने के साथ घूमना जारी रखा जा सके।लैम्ब्डा अभिव्यक्ति

import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.ReentrantLock; 

interface Predicate { 
    public void test() throws InterruptedException; 
} 

class MyClass { 
    int num = 0; 
    Lock lock = new ReentrantLock(); 

    public void produce() throws InterruptedException { 
     lock.lock(); 
     for (int i = 0; i < 1000; i++) { 
      num++; 
      Thread.sleep(1); 
     } 
     lock.unlock(); 
    } 

    public void consume() throws InterruptedException { 
     lock.lock(); 
     for (int i = 0; i < 1000; i++) { 
      num--; 
      Thread.sleep(1); 
     } 
     lock.unlock(); 
    } 

    public int getNum() { 
     return num; 
    } 

} 

public class Main00 { 

    public static void main(String[] args) throws InterruptedException { 
     MyClass c = new MyClass(); 
     Predicate prod = c::produce; 
     Predicate cons = c::consume; 
     Thread t1 = new Thread(() -> prod.test()); 
     Thread t2 = new Thread(() -> cons.test()); 
     long start = System.currentTimeMillis(); 
     t1.start(); 
     t2.start(); 
     t1.join(); 
     t2.join(); 
     long end = System.currentTimeMillis(); 
     System.out.println("time taken " + (end - start) + " num = " 
       + c.getNum()); 
    } 

} 

उत्तर

10

आप एक कार्यात्मक इंटरफ़ेस Predicate जिसका विधि घोषित किया जाता है एक InterruptedException है, जो एक जाँच अपवाद नहीं है फेंक बनाया है। हालांकि, आप पर पैरामीटर के रूप में लैम्ब्डा अभिव्यक्ति के शरीर में test() पर कॉल करते हैं। इसलिए, क्योंकि अपवाद शरीर में पकड़ा नहीं जाता है, एक संकलक त्रुटि होती है।

संयोग से, यह, अपने स्वयं के इंटरफेस Predicate नाम के लिए भ्रमित हो सकता है की वजह से built-in functional interface java.util.function.Predicate जिसका कार्यात्मक विधि देता है एक boolean

क्योंकि run()Exception फेंक नहीं सकता है, आपको catch अपवाद और इसे संभालना होगा। आप अपवाद और इसके स्टैक ट्रेस लॉग कर सकते हैं। आप अपवाद को RuntimeException में लपेट सकते हैं। किसी भी तरह से, चेक अपवाद को पकड़ने से कोड को संकलित करने की अनुमति मिल जाएगी। उदाहरण:

Thread t1 = new Thread(() -> { 
    try { 
     prod.test(); 
    } catch (InterruptedException e) { 
     // handle: log or throw in a wrapped RuntimeException 
     throw new RuntimeException("InterruptedException caught in lambda", e); 
    } 
}); 
3

@rgettman कहते हैं, नाम Predicate दुखी है ... फिर भी, आप जावा में default तरीकों का लाभ ले सकता है:

interface PredicateButPleaseChangeMyName { 

    void test() throws InterruptedException; 

    default void tryTest() { 
     try { 
      this.test(); 
     } catch (InterruptedException e) { 
      // handle e (log or wrap in a RuntimeException) 
     } 
    } 
} 

फिर, अपने मुख्य विधि में, बस बनाने डिफ़ॉल्ट tryTest() विधि को कॉल करके धागे:

Thread t1 = new Thread(() -> prod.tryTest()); 
Thread t2 = new Thread(() -> cons.tryTest()); 
संबंधित मुद्दे