文章参考 Future 详解
在线程池中,我们知道调用future.get()方法是会阻塞当前线程,知道得到get方法的返回值之后才继续运行,所以future是异步编程?
线程池中的提交任务的方法有两种,一个是 execute,参数是 Runnable方法,返回值是 void方法; 第二种方式是 submit方法: 有三种 submit。这三种按照提交任务的类型来算分为两个类型。
提交执行 Runnable 类型的任务。
提交执行 Callable 类型的任务。
但是返回值都是 Future,这才是我们关心的东西。
在submit中可以通过传入参数得到返回值: 示例如下:
public class ThreadPoolExecutorTest { public static void main(String[] args) throws Exception { ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 5, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10)); AtomicInteger atomicInteger = new AtomicInteger(); Future<AtomicInteger> future = executor.submit(() -> { System.out.println("测试"); //在这里进行计算逻辑 atomicInteger.set(5201314); }, atomicInteger); System.out.println("future的内容:" + future.get()); Thread.currentThread().join(); //防止主线程退出 } }其中调用的 get()方法是阻塞的,描述可得: 所以总结一下这种场景下返回的 Future 的不足之处:
只有主动调用 get 方法去获取值,但是有可能值还没准备好,就阻塞等待。
任务处理过程中出现异常会把异常隐藏,封装到 Future 里面去,只有调用 get 方法的时候才知道异常了。
增加了一个监听方法,执行完成后通知!!!
public static void main(String[] args) throws InterruptedException { // 1. 初始化executor ListeningExecutorService executor = MoreExecutors.listeningDecorator( Executors.newCachedThreadPool()); // 2. 要执行的任务 ListenableFuture<String> listenableFuture = executor.submit(() -> { System.out.println(Thread.currentThread().getName() + "-女神:我开始化妆了,好了我叫你。"); TimeUnit.SECONDS.sleep(5); return "化妆完毕!!"; }); // 3. 设置监听器函数执行回调 listenableFuture.addListener(() -> { try { System.out.println(Thread.currentThread().getName()+"-future的内容:" + listenableFuture.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }, executor); // 主线程任务,不会被阻塞 System.out.println(Thread.currentThread().getName()+"-等女神化妆的时候可以干点自己的事情。"); Thread.currentThread().join(); }另一种实现方法 FutureCallback 方式:
public class JDKThreadPoolExecutorTest { public static void main(String[] args) throws Exception { ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()); ListenableFuture<String> listenableFuture = executor.submit(() -> { System.out.println(Thread.currentThread().getName()+"-女神:我开始化妆了,好了我叫你。"); TimeUnit.SECONDS.sleep(5); return "化妆完毕了。"; }); Futures.addCallback(listenableFuture, new FutureCallback<String>() { @Override public void onSuccess(@Nullable String result) { System.out.println(Thread.currentThread().getName()+"-future的内容:" + result); } @Override public void onFailure(Throwable t) { System.out.println(Thread.currentThread().getName()+"-女神放你鸽子了。"); t.printStackTrace(); } }); System.out.println(Thread.currentThread().getName()+"-等女神化妆的时候可以干点自己的事情。"); Thread.currentThread().join(); } }原文请看置顶连接