java中的Callable vs Supplier接口

aru*_*kjn 8 java functional-interface

CallableSupplier在功能接口java.util.concurrentjava.util.function包分别具有以下签名工具

public interface Callable<V> {
    V call() throws Exception;
}

public interface Supplier<T> {
    T get();
}
Run Code Online (Sandbox Code Playgroud)

是否有一些特定的用例,其中每一个都比另一个更适合?

And*_*son 16

来龙去脉

对于RunnableCallable,自 Java 6 以来它们一直是并发包的一部分。这意味着它们都已准备好提交到Executor并异步运行。这里Callable有具体的用法。

而对于Runnable(0 in 0 out)、Supplier(0 in 1 out)、Consumer(1 in 0 out) 和Function(1 in 1 out),它们从 Java 8 开始就成为功能特性的一部分。所有这些都已准备好由 lambda 友好的东西处理,例如CompletableFuture. 这里Supplier只是指没有任何输入参数但有返回值的函数,这是高度抽象的。

0 在(参数) 1 英寸(参数)
0 出(返回) Runnable Consumer
1 出(已退回) Supplier Function

  • 你的“进出”分析对我很有启发。谢谢。我添加了一个表格来可视化该分析。 (4认同)

Swe*_*per 9

它们的使用差异可以从各自的文档中看出:

Callable:

返回结果并可能抛出异常的任务.实现者定义一个没有名为call的参数的方法.

Callable接口类似于Runnable,因为它们都是 为其实例可能由另一个线程执行的类而设计的.

Supplier:

代表结果的供应商.

每次调用供应商时都不要求返回新的或不同的结果.

这意味着调用者Callable.call期望抛出异常并相应地处理异常.这对于读取和写入文件等任务非常有用,IOException可以抛出多种类型的文件.Callable也被设计为在另一个线程上运行.

Supplier另一方面,很一般.它只是"提供价值",就是这样.

因此Callable更专业Supplier.如果您没有处理另一个线程或者您的任务不太可能抛出异常,Supplier建议您使用.


Tor*_*ben 7

除了明显的 Callable 抛出异常之外,区别在于语义。它们有不同的名称,因为它们代表不同的事物。目的是让代码更容易理解。当您使用 Callable 时,您的接口选择意味着该对象将由另一个线程执行。当您使用 Supplier 时,您暗示它只是一个向另一个组件提供数据的对象。

  • 除了命名语义之外,在实现级别上是否有什么东西可以使 Callable 在多线程环境中成为更好的选择?在多线程上下文中使用Supplier是否不安全? (2认同)
  • 没有不同。它们只是接口。 (2认同)