简短答案
不,用
Callable代替
Supplierin
是不自然的
CompletableFuture.supplyAsync。该论点几乎完全是关于语义的,因此,如果您此后仍不确信,那就可以了。
长答案
的
Callable和
Supplier功能接口/ SAM类型在功能几乎等同(原谅双关语),但它们的起源和预期用途而不同。
Callable
是作为
java.util.concurrent软件包的一部分创建的。该程序包是在Java
8中的lambda表达式发生巨大变化之前进行的,最初集中在一系列工具上,这些工具可帮助您编写并发代码,而又不会偏离经典的动手多线程模型。
的主要目的
Callable是抽象一个可以在不同线程中执行并返回结果的动作。从
Callable的Javadoc:
该
Callable接口与相似Runnable,因为两者都是针对其实例可能由另一个线程执行的类设计的。
Supplier
是作为
java.util.function软件包的一部分创建的。该软件包是上述Java
8更改的组成部分。它提供了lambda表达式和方法引用可以作为目标的通用功能类型。
一种这样的类型是没有返回结果的参数的函数(即提供某种类型的
Supplier函数或函数)。
那么为什么Supplier
不Callable
呢?
CompletableFuture是对该
java.util.concurrent软件包进行补充的一部分,该软件包的灵感来自于Java
8中的上述更改,并且允许开发人员以功能性,隐式可并行化的方式构造其代码,而不是显式地处理其中的并发。
它的
supplyAsync方法需要一种方法来提供特定类型的结果,并且它对该结果更感兴趣,而不是为达到该结果而采取的措施。它也不一定要关心出色的完成效果(另请参见下面的
“关于…的内容” 部分)。
仍然,如果Runnable
用于无参数,无结果的功能接口,是否不Callable
应该用于无参数,无结果的功能接口?
不必要。
没有参数且不返回结果(因此完全通过外部上下文的副作用进行操作)的函数的抽象未包含在中
java.util.function。这意味着
Runnable在需要这种功能接口的任何地方都使用(有些令人讨厌)。
怎么样的检查Exception
可以通过抛出Callable.call()
?
这是
Callable和之间预期的语义差异的一个小标志
Supplier。
A
Callable是可以在另一个线程中执行的操作,它使您可以检查其执行后的副作用。如果一切顺利,您将得到特定类型的结果,但是由于执行某些操作时可能会出现异常情况(尤其是在多线程上下文中),因此您可能还需要定义和处理此类异常情况。
Supplier另一方面,A 是您提供某种类型的对象所依赖的功能。特殊情况不一定作为您的直接消费者承担责任
Supplier。这是因为:
- …功能接口通常用于定义多阶段过程中的特定阶段,以创建或更改数据,并且处理
Exception
s可以是一个单独的阶段,以防万一 - …显式处理
Exception
s会大大降低功能接口,lambda表达式和方法引用的表达能力



