Callable
主要是用于后台获取数据,就像Thread.join()
一样,可以当前线程等待后台线程执行返回。
Callable
与Runnable
相似,都是函数式接口,都只是描述了执行方法。不过Callable
是通过call()
方法执行,允许抛出异常,并且需要一个返回值。
Callable
一般是和FutureTask
结合使用。看源码不难得知,FutureTask
实现了RunnableFuture
接口,那么它就拥有Runnable
与Future
的特性。
所以我们可以通过Thread
的方式来执行它,例如:
1 | Callable<String> callable = () -> { |
这里所得的结果就是:
1 | main |
这是因为在执行FutureTask.get()
方法时,就像Thread.join()
一样,需要等待Callable
执行完毕并返回。
为什么不使用Runnable+Thread.join()
如果我们定义了变量,我们同样可以使用Thread.join()
来同步线程的数据获取流程。但是Runnable
是不能抛出异常的,也就是在数据获取的过程中出现错误是没办法直接反馈给获取方的。这就导致了通过Runnable
方式来获取数据只能得到结果,错误结果只能在Runnable
内部消化,这样可能会导致耦合度变高。
还有一点,由于FutureTask
是Future
接口的实现类,所以我们可以通过FutureTask
来对这个异步任务进行取消或是确认完成的操作,这对一些自动化任务很有帮助。
并且FutureTask
也为我们提供了new FutureTask(Runnable runnable, V result)
的构造方法,可以兼容Runnable
执行体。