背景
异步编程现在受到了越来越多的关注,尤其是在IO密集型的业务场景中,相比传统的同步开发模式,异步编程的优势越来越明显,本文介绍Java常见的实现方式;
Future
描述
java.util.concurrent.Future是JDK5引入的,用来获取一个异步计算的结果。可以使用isDone方法检查计算是否完成,也可以使用get阻塞住调用线程,直到计算完成返回结果,使用cancel方法停止任务的执行。
FutureTask.java是对Futre和Runnable最简单的实现,实现了run函数,所以可以直接执行,任务执行结束通过set()保存结果,setException()保存异常信息。通常配合executorService.submit()一起使用,ExecutorService中将任务包装成FutureTask执行execute();
样例
@Test
????public?void?futureCallBackTest()?throws?InterruptedException,?ExecutionException?{
????????System.out.println(printThread("小明点餐"));
????????Future<String>?future?=?executorService.submit(()?->?{
????????????System.out.println(printThread("厨师开始炒菜"));
????????????Thread.sleep(2000);
????????????System.out.println(printThread(?"厨师炒好菜"));
????????????return?"饭菜好了";
????????});
????????String?result?=?future.get();
????????executorService.shutdown();
????????System.out.println(printThread(result?+?",小明开始吃饭"));
????}
运行结果
优缺点
-
能获得异步线程执行结果
-
无法方便得知任务何时完成
-
在主线程获得任务结果会导致主线程阻塞
-
复杂一点的情况下,比如多个异步任务的场景,一个异步任务依赖上一个异步任务的执行结果,异步任务合并等,Future无法满足需求
ListenableFuture
描述
Google并发包下的listenableFuture对Java原生的future做了扩展,顾名思义就是使用监听器模式实现的回调,所以叫可监听的future,通过addListener(Runnablelistener,Executorexecutor)方法添加回调任务。
要使用listenableFuture还要结合MoreExecutor线程池,MoreExecutor是对Java原生线程池的封装,比如常用的MoreExecutors.listeningDecorator(threadPool);修改Java原生线程池的submit方法,封装了future返回listenableFuture。
样例
@Test
????public?void?listenableFutureTest()?throws?InterruptedException,?ExecutionException?{
????????System.out.println(printThread("小明点餐"));
????????ListeningExecutorService?listeningExecutorService?=?MoreExecutors.list