当我们用Java编写多线程应用程序时,我们倾向于使用“ Runnable ”接口来实现线程类。
您的类必须简单地实现此接口并覆盖run方法。
对于琐碎的用例,我们可以通过调用“ start”方法直接启动线程,结果将控制流委托给run方法。
但是,在大多数应用程序中,我们最终使用线程池,该线程池管理工作线程并在任务提交到池时促进任务执行。
Java提供了各种各样的线程池,并且还允许程序员创建自己的线程池实现。
将线程任务提交给池的过程也很标准。
在某些情况下,我们可能希望我们的线程做更多的事情,而不是仅仅执行一个任务。
在这种情况下,了解使用Runnable vs Callable的用例很重要。
1.从执行线程返回值
在许多情况下,您可能希望从执行线程返回一个值。
这是“可调用”任务派上用场的地方。
Java ExecutorService API允许接受Callable类型的任务,并返回“ Future”任务。
这对于某些用例可能很有用。
但是,下面给出了使用Callable的更重要的选择之一。
2.能够从执行线程中抛出检查异常
Callable的重要考虑因素之一是程序员具有从执行线程中引发异常的能力。
这可以从我们的多线程应用程序中处理异常,并可以从异常中正常恢复。
如果我们查看“调用”方法的签名,就会发现它引发了一个通用异常–
V call()引发异常
3.其他方案
Callable接口实现也可以与FutureTask结合使用。
FutureTask类接受Callable实现。
FutureTask可以提交给线程池执行器,我们可以使用标准的Future API检索执行结果。
下面的代码段
public class CallableInsideFutureTask{public static void main(String[] args){ExecutorService executor = Executors.newSingleThreadExecutor();FutureTask<String> myTask = new MyTask(new CallableTest());executor.submit(myTask);try {myTask.get();} catch (Exception ex ) {ex.printStackTrace();}executor.shutdownNow();}}
在此示例中, CallableTest类必须实现Callable接口。
如果您喜欢这篇文章,请随时在LinkedIn上进行连接。
翻译自: https://www.javacodegeeks.com/2019/04/callable-runnable-tasks-java-concurrent-programming.html