Thread with Lambda expression

前端 未结 3 1155
耶瑟儿~
耶瑟儿~ 2021-01-04 02:39

I have an error at line 42 and 43 : Thread t1=new Thread(()->prod.test()); , Thread t2=new Thread(()->cons.test()); Unhandled exception t

相关标签:
3条回答
  • 2021-01-04 03:04

    You have created a functional interface Predicate whose method is declared to throw an InterruptedException, which is a checked exception. However, you call test() in the body of a lambda expression as the parameter to the Thread constructor that takes a Runnable, whose run() method is not declared to throw any checked exceptions. Therefore, because the exception is not caught in the body, a compiler error occurs.

    Incidentally, it may be confusing to name your own interface Predicate, because of the built-in functional interface java.util.function.Predicate whose functional method returns a boolean.

    Because run() can't throw an Exception, you must catch the exception and handle it. You might log the exception and its stack trace. You might wrap the exception in a RuntimeException. Either way, catching the checked exception will allow the code to compile. Example:

    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);
        }
    });
    
    0 讨论(0)
  • 2021-01-04 03:22

    As @rgettman says, the name Predicate is unhappy... Anyways, you could take advantage of default methods in Java:

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

    Then, in your main method, simply create the threads by calling the default tryTest() method:

    Thread t1 = new Thread(() -> prod.tryTest());
    Thread t2 = new Thread(() -> cons.tryTest());
    
    0 讨论(0)
  • 2021-01-04 03:24

    If you intend on running a single method only with no arguments you can replace the lambda with a method reference.

    For instance:

    Thread t = new Thread(() -> {
            foo();
        });
    

    can be more succinctly expressed as

    Thread t = new Thread(this::foo);
    
    0 讨论(0)
提交回复
热议问题