2015-07-14 6 views
10

У меня есть ошибка в строке 42 и 43: Thread t1=new Thread(()->prod.test());, Thread t2=new Thread(()->cons.test());Необработанный тип исключения InterruptedException. Если я попытаюсь выполнить fastfix, он создаст попытку catch с уловом Exception, он будет иметь такую ​​же ошибку и попытается исправить ее таким же образом, продолжая окружать ее с помощью try catch.Нить с выражением Лямбда

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() в тело лямбда-выражения в качестве параметра the Thread constructor that takes a Runnable, чей run() method is not declared to throw any checked exceptions. Поэтому, поскольку исключение не попадает в тело, возникает ошибка компилятора.

Кстати, это может ввести в заблуждение имя вашего собственного интерфейса 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 методов в Java:

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()); 
Смежные вопросы