completablefuture供应同步

k97glaaz  于 2021-07-13  发布在  Java
关注(0)|答案(1)|浏览(359)

我刚刚开始研究Java8的一些并发特性。有一件事让我有点困惑,那就是这两种静态方法:

CompletableFuture<Void> runAsync(Runnable runnable) 
CompletableFuture<U> supplyAsync(Supplier<U> supplier)

有人知道他们为什么选择使用接口供应商吗?使用callable不是更自然吗?callable类似于runnable,返回一个值?这是因为供应商没有抛出无法处理的异常吗?

8fq7wneg

8fq7wneg1#

简短的回答
不,用起来不自然 Callable 而不是 SupplierCompletableFuture.supplyAsync . 这个论点几乎完全是关于语义的,所以如果你事后仍然觉得不可信,那也没关系。
冗长的回答
这个 Callable 以及 Supplier 功能接口/sam类型实际上在功能上是等价的(请原谅双关语),但是它们的起源和预期用途不同。 Callable 是作为 java.util.concurrent 包裹。这个包出现在java8中lambda表达式的巨大变化之前,最初集中在一系列帮助您编写并发代码的工具上,而没有偏离传统的手工多线程模型。
主要目的 Callable 是抽象一个可以在不同线程中执行并返回结果的操作。从 Callable 的javadoc:
这个 Callable 接口类似于 Runnable ,因为它们都是为其示例可能由另一个线程执行的类而设计的。 Supplier 是作为 java.util.function 包裹。这个包是Java8中上述更改的一个组成部分。它提供了lambda表达式和方法引用可以作为目标的常见函数类型。
其中一种类型是不带返回结果的参数的函数(即提供某种类型或参数的函数) Supplier 函数)。
那为什么呢 Supplier 而不是 Callable ? CompletableFuture 是对 java.util.concurrent 这个包的设计灵感来自于java8中的上述更改,它允许开发人员以一种功能性的、隐式可并行的方式构造代码,而不是显式地处理其中的并发性。
supplyAsync 方法需要一种方法来提供一个特定类型的结果,它更感兴趣的是这个结果,而不是为了达到这个结果而采取的行动。它也不一定关心特殊的完成(也看到了什么关于。。。下一段)。
尽管如此,如果 Runnable 用于没有参数,没有结果的函数接口,不应该 Callable 是否用于无参数、单结果功能接口?
不一定。
对于没有参数且不返回结果(因此完全通过外部上下文的副作用进行操作)的函数的抽象未包含在中 java.util.function . 这意味着(有点恼人) Runnable 在需要这种功能接口的地方使用。
那支票呢 Exception 可以由 Callable.call() ?
这是一个很小的迹象表明 Callable 以及 Supplier .
Callable 是一个可以在另一个线程中执行的操作,它允许您检查其执行的副作用。如果一切顺利,您会得到一个特定类型的结果,但由于在执行某些操作(尤其是在多线程上下文中)时可能会出现异常情况,因此您可能还需要定义和处理此类异常情况。
Supplier 另一方面是一个函数,您依赖它来提供某种类型的对象。例外情况不一定是您作为产品直接消费者的责任 Supplier . 这是因为:
…功能接口通常用于定义多阶段流程中的特定阶段,以创建或更改数据并进行处理 Exception 如果你介意的话,s可以是一个单独的阶段
…显式处理 Exception s显著降低了函数接口、lambda表达式和方法引用的表达能力

相关问题