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