sch*_*boi 62 java lambda multithreading compilation functional-interface
我的问题是关于InterruptedException,它是从Thread.sleep方法中抛出的。在合作时,ExecutorService我注意到一些我不理解的怪异行为;这是我的意思:
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
while(true)
{
//DO SOMETHING
Thread.sleep(5000);
}
});
Run Code Online (Sandbox Code Playgroud)
有了这个代码,编译器不给我任何错误或消息InterruptedException从Thread.sleep应该被抓。但是,当我尝试更改循环条件并用诸如此类的变量替换“ true”时:
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
while(tasksObserving)
{
//DO SOMETHING
Thread.sleep(5000);
}
});
Run Code Online (Sandbox Code Playgroud)
编译器不断抱怨InterruptedException必须处理。有人可以向我解释为什么会发生这种情况,为什么将条件设置为true则编译器会忽略InterruptedException?
Mar*_* R. 63
这样做的原因是,这些调用实际上是对ExecutorService;中可用的两种不同的重载方法的调用。这些方法中的每一个均采用不同类型的单个参数:
<T> Future<T> submit(Callable<T> task);Future<?> submit(Runnable task);
然后发生的是,编译器将问题的第一种情况下的lambda转换为Callable<?>功能接口(调用第一个重载方法);在问题的第二种情况下,将lambda转换为Runnable功能接口(因此调用第二个重载方法),因此需要处理该Exception抛出的问题;但在以前的情况下不使用Callable。
尽管两个功能接口均不接受任何参数,但Callable<?> 返回值:
- 可致电:
V call() throws Exception;- 可运行的:
public abstract void run();
如果我们切换到将代码修整到相关部分的示例(以便轻松地研究好奇的位),那么我们可以编写与原始示例等效的代码:
ExecutorService executor = Executors.newSingleThreadExecutor();
// LAMBDA COMPILED INTO A 'Callable<?>'
executor.submit(() -> {
while (true)
throw new Exception();
});
// LAMBDA COMPILED INTO A 'Runnable': EXCEPTIONS MUST BE HANDLED BY LAMBDA ITSELF!
executor.submit(() -> {
boolean value = true;
while (value)
throw new Exception();
});
Run Code Online (Sandbox Code Playgroud)
通过这些示例,可能更容易观察到第一个被转换为a Callable<?>,而第二个被转换为a Runnable的原因是由于编译器推断。
在这两种情况下,lambda主体都是无效的,因为该块中的每个return语句都具有形式return;。
现在,在第一种情况下,编译器将执行以下操作:
throw new <CHECKED_EXCEPTION>()。complete normally,因此是值兼容的。Callable<?>和Runnable是该lambda的潜在匹配项,因此编译器会选择最具体的匹配项(以涵盖所有情况)。这是Callable<?>,将lambda转换为其实例,并创建对submit(Callable<?>)重载方法的调用引用。在第二种情况下,编译器执行以下操作:
complete normally。Runnable(因为它是要转换为lambda 的唯一可用的拟合功能接口),并创建对submit(Runnable)重载方法的调用引用。所有这些都是以委托给用户为代价的,即有责任处理可能在lambda主体内的任何位置Exception抛出的任何东西。这是一个很好的问题-追逐它让我很开心,谢谢!