【问题标题】:How does java differentiate Callable and Runnable in a Lambda?java如何区分Lambda中的Callable和Runnable?
【发布时间】:2018-08-14 19:32:53
【问题描述】:

我得到了这个小代码来测试Callable。但是,我发现编译器如何知道 Lambda 是用于接口 Callable 还是 Runnable 非常令人困惑,因为它们的函数中都没有任何参数。

然而,IntelliJ 显示 Lambda 使用 Callable 的代码。

public class App {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.submit(() ->{
            System.out.println("Starting");
            int n = new Random().nextInt(4000);
            try {
                Thread.sleep(n);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                System.out.println("Finished");
            }
            return n;
        });
        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.MINUTES );
    }
}

【问题讨论】:

  • 它返回一个结果,Runnable 没有,所以它是一个 Callable。
  • 语言规范中的关键短语是“void compatible”和“value compatible”。
  • @Michael 这是一个简单的解释:您可以使用一些将返回值作为可运行对象的 lambda(例如 () -> Integer.valueOf(0)),在这种情况下,返回值将被丢弃。
  • @AndyTurner 那是一个表达式 lambda,OP 没有使用,规则不同。您不能编写关键字return 并忽略结果。

标签: java multithreading lambda java-8 functional-interface


【解决方案1】:

参见 ExecutorService 的文档,它有 2 个 submit 方法和一个参数:

你的 lambda 给出一个输出,返回一些东西:

executorService.submit(() -> {
    System.out.println("Starting");
    int n = new Random().nextInt(4000);
    // try-catch-finally omitted
    return n;                                      // <-- HERE IT RETURNS N
});

所以 lambda 必须是 Callable&lt;Integer&gt;,这是以下的快捷方式:

executorService.submit(new Callable<Integer>() {
    @Override
    public Integer call() throws Exception {
        System.out.println("Starting");
        int n = new Random().nextInt(4000);
        // try-catch-finally omitted
        return n;  
    }}
);

为了比较,用Runnable做同样的事情,你会看到它的方法的返回类型是void

executorService.submit(new Runnable() {
    @Override
    public void run() {
        // ...  
    }}
);

【讨论】:

  • 混淆:“三个 submit 方法只有一个参数”但你只列出了 2...(你的意思是 2,因为我相信只有 2 和 1参数)
  • @CarlosHeuberger:这是一个错字。我的意思是列出所有 3 个 submit 方法,但是后来我意识到只有 2 个有意义,并且意外地留下了“3”。谢谢。
【解决方案2】:

签名的主要区别在于Callable 返回一个值,而Runnable 不返回。所以你代码中的这个例子是Callable,但肯定不是Runnable,因为它返回一个值。

【讨论】:

    猜你喜欢
    • 2019-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    相关资源
    最近更新 更多