什么时候应该更喜欢 Callable 而不是 Runnable,为什么?

When should prefer Callable over Runnable and why?

在 SO 上,我发现 CallableRunnable 之间的所有理论差异几乎都是相似的。但是,我不明白为什么在以后的版本中引入了Callable? Runnable 中的 gap/flaws 是什么,Callable 能够做什么?任何人都可以解释 Callable 是唯一解决方案的场景吗?

嗯,documentation 确实回答了你问题的很大一部分:

The Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially executed by another thread. A Runnable, however, does not return a result and cannot throw a checked exception.

因此,如果...

,您正在使用 Callable 而不是 Runnable
  1. 您需要抛出一个已检查异常或...
  2. 你需要 return 一个对象(当然你可以通过给你的 runnable 一个内部结果对象等来模拟这个 - 但这样更容易)

例如...

ExecutorService service = ... some ExecutorService...;
Callable<Integer> myCallable = new MyCallable( ... some parameters ... );
Future<Integer> future = service.submit( myCallable );
...
Integer myResult = future.get(); // will wait and return return value from callable as soon as done

Callable 有两个区别。它可以 return 一个值或抛出一个已检查的异常。

这在使用 lambda 时会有所不同,因此即使您没有指定要起诉哪个,编译器也必须解决它。

// the lambda here must be a Callable as it returns an Integer
int result = executor.submit(() -> return 2);

// the lambda here must be a Runnable as it returns nothing
executors.submit(() -> System.out.println("Hello World"));

// the lambda here must be a Callable as an exception could be thrown
executor.submit(() -> {
   try (FileWriter out = new FileWriter("out.txt")) {
      out.write("Hello World\n");
   }
   return null; // Callable has to return something
});