Thread with Lambda expression
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); }});
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);
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());