从这个answer我了解到,Callable
和Runnable
之间的唯一区别是前者可以返回执行结果并抛出异常。
我不明白为什么Executor
没有定义采用Callable
的方法:
void execute(Callable command);
从我的观点来看,为Runnable
和Callable
创建方法是合乎逻辑的。在ExecutorService
Executor
的子接口中,submit()
和Runnable
都有类似的Callable
方法。
请解释这个设计决定,因为我在互联网上找不到任何解释。
答案 0 :(得分:2)
我认为Executor设计应该尽可能简单,即使用一种方法。由于execute()没有提供任何获取结果的方法,因此它不接受Callables,只接受Runnables。
另一方面,各种submit()函数返回Futures,它可用于获取结果(例如来自Callable),或者只是等待执行完成。因此,接受Runnable和Callable都是有意义的。
答案 1 :(得分:2)
执行人员运行任务。如果要管理应该如何以及何时运行任务,则需要它们。执行者不收集任务结果,因此仅支持Runnable
。
假设他们支持Callable
。那么如何获取结果呢? T execute(Callable<T> command)
不是一个选项,因为它会阻止当前的线程执行。因此,它应与某些T getResult()
配对或返回Future<T>
。为此,您ExecutorService
使用方法<T> Future<T> submit(Callable<T> task)
。
答案 2 :(得分:2)
我不明白为什么
Executor
没有定义一个Callable
的方法。
Executor
只有一个责任 - 执行提交的任务。在此抽象级别上,仅使用Runnable
的API不需要ExecutorService
提出的其他功能。
为
Runnable
和Callable
创建方法符合逻辑。
是的,因此ExecutorService
界面是通过扩展Executor
来设计的。 ExecutorService
提供了显着的差异 - 提供任务执行结果。这就是添加Callable
,TimeUnit
和生命周期方法的原因。< / p>