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