Callable
Runnable
虽然方便但是不能让tasks的执行拥有返回值。
Java还提供了Callable
接口来让tasks返回结果。Callable
和Runnable
类似,除了可以返回结果以及会抛出一个checked exeption。
Callable
接口拥有单个方法call()
:
|
|
Callable
不需要在Thread.sleep()
外使用try/catch代码块,因为Callable可以抛出checked exception
TODOJava中checked exception指什么?
使用lambda表达式:
|
|
Executing Callable tasks using ExecutorService and obtaining the result using Future
Executor servicesubmit()
方法可以提交task给线程执行,但是并不知道什么时候结果可以被获取。因此,它返回来一种特殊的类型Future
。这个类型可以用于在结果准备好之后获取结果。
Future
的概念和其他语言如JavaScript中的Promise
相似。
Future
represents the result of a computation that will be completed at a later point of time in future.
|
|
|
|
ExecutorService.submit()
会直接返回Future
。一旦拿到它,就可以并行执行其他tasks,这时候之前提交的task还在执行。之后可以用future.get()
来获取结果。
get()
方法会阻塞,直到任务完成。Future
API也提供了一个isDone()
方法来判断task是否完成。
|
|
|
|
Cancelling a Future
Future.cancel()
可以取消future。返回一个boolean表示是否取消成功。
cancel()
方法接收mayInterruptIfRunning
参数。true
表示如果这个task正在执行就会被中断执行,false
表示如果正在执行会等待执行完毕。
|
|
|
|
Task被取消后,future.get()
会抛出CancellationException
异常。改进:
|
|
Adding Timeouts
future.get()
会阻塞线程并等待task完成,如果不设置超时选项,future.get()
在任务无法完成的情况下会被永远阻塞。
|
|
如果无法再规定时间内完成,会抛出TimeoutException
。
invokeAll
提交多个tasks,并且等待他们全部完成。
可以提交Callables的集合给invokeAll()
方法,它会返回Futures的列表。任何一个future.get()
的调用都会被阻塞,除非全部完成。
|
|
|
|
invokeAny
批量提交,等待任一完成。
invokeAny()
方法会接受Callables
集合,返回执行最快的Callable的结果。它不会返回Future。
|
|
|
|