Future
Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。
FutureTask缺点:
get不管计算是否完成都要阻塞
优化:
1.get设置参数超时抛出异常
2.轮训代替阻塞,isDone方法,但是后续的方法还是不能执行,但是轮训可以设置时间多久一次,还是比阻塞好
3.异步任务调度编排(线程依赖其余某几个线程的结果+不阻塞= 例1 )
CompletableFuture既有Future的功能又有ComletetionStage的功能,扩展增强思想
ComletetionStage一个阶段完成后触发其他阶段
CompletableFuture.runAsync() 无返回值
CompletableFuture.supplyAsync() 有返回值
方法不以Async结尾,意味着Action使用相同的线程执行,而Async可能会使用其它的线程去执行(如果使用相同的线程池,也可能会被同一个线程选中执行)。
这几个方法都会返回CompletableFuture,当Action执行完毕后它的结果返回原始的CompletableFuture的计算结果或者返回异常
都可传自定义线程池,否则有自带的
- 使用CompletableFuture一定要自定义线程池
- CompletableFuture是否使用默认线程池和机器核心数有关,当核心数减1大于1时才会使用默认线程池,否则将为每个任务创建一个新线程去处理
- 即便使用到了默认线程池,池内最大线程数也是核心数减1,对io密集型任务是远远不够的,会令大量任务等待,降低吞吐率
- ForkJoinPool比较适用于CPU密集型的任务,比如说计算。
例1
例子中,thnApply和thenCompose都是将一个CompletableFuture转换为CompletableFuture。不同的是,thenApply中的传入函数的返回值是String(f=1),而thenCompose的传入函数的返回值是CompletableFuture
thnApply对比handel
handel可以处理异常,流程可以继续往下走
thnApply异常直接抛出到外层
whenComplete
get抛出异常 join不会抛出异常
getNow(default) 计算完毕返回值,没计算完成返回default默认值
complete(value)打断,返回布尔值,调用后如果计算完成在get返回值,如果没计算完调用get返回自定义的value
applyToEither 谁快返回谁的值
thenCombine 等待每个结果后进行计算