zoukankan      html  css  js  c++  java
  • Guava 并行 Futures实例

    Future可以用来构建复杂的异步操作,方法不是返回一个值,而是一个Future对象。创建Future对象的过程(比如调用Future异步函数接口),不会阻塞当前线程操作,而且对象第一个次创建没有值,但以后可以通过这个对象获取这个值。Guava中的ListenableFuture接口对java.util.concurrent.Future接口做了进一步拓展,并且提供了Futures静态工具类,大大方便了我们的使用。本文主要介绍Guava Future的使用,给出了几个使用的例子。

    Code Test Case

    多任务并发执行,不阻塞当前线程

        @Test
        public void should_run_future_tasks_in_parallel() throws Exception {
            ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
            ListenableFuture<?> task1 = service.submit(new Runnable() {
                public void run() {
                    try {
                        Thread.sleep(2000);
                        System.out.println("future task1 done.....");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            ListenableFuture<?> task2 = service.submit(new Runnable() {
                public void run() {
                    try {
                        Thread.sleep(2000);
                        System.out.println("future task2 done.....");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
    
            System.out.println("main task done.....");
            Thread.sleep(3000);
        }
    

    可以使用get操作获取Future值,阻塞当前线程,直到异步操作逻辑处理完毕

        @Test
        public void should_block_the_current_thread() throws Exception {
            ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
            ListenableFuture<Integer> task = service.submit(new Callable<Integer>() {
                public Integer call() throws Exception {
                    Thread.sleep(2000);
                    System.out.println("future task done......");
                    return 1;
                }
            });
            System.out.println(task.get());
            System.out.println("main task done.....");
        }
    

    get函数提供下面两个接口,用户可以根据需要选择是否添加超时。

        V get() throws InterruptedException, ExecutionException; 
        V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;
    

    处理异步Future,可以使用callback,在callback函数中对异步处理的结果进行处理。callback函数不阻塞当前线程。

        @Test
        public void should_call_back_the_future_task() throws Exception {
            ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
            ListenableFuture<Integer> task = service.submit(new Callable<Integer>() {
                public Integer call() throws Exception {
                    Thread.sleep(2000);
                    System.out.println("future task done......");
                    return 1;
                }
            });
            Futures.addCallback(task, new FutureCallback() {
                public void onSuccess(Object o) {
                    System.out.println("异步处理成功,result="+o);
                }
    
                public void onFailure(Throwable throwable) {
                    System.out.println("异步处理失败,e="+throwable);
                }
            });
    
            System.out.println("main task done.....");
            Thread.sleep(3000);
        }
    

    例子中使用的Futures.addCallBack函数,第一个参数为我们要处理的异步Future task,它可以是一个数据库处理,可以是一个外部模块API请求等;第二个参数我们使用的是FutureCallBack匿名构造对象,对象内实现两个方法,onSuccess和onFailure。future task处理成功,没有任何异常则分支进入onSuccess处理,否则进入onFailure分支。

    将Future对象转化为另一个Future对象

    例子中将task的结果转化为Boolean类型的future对象

        @Test
        public void should_transform_to_another_future_obj() throws Exception {
            ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
            ListenableFuture<Integer> task = service.submit(new Callable<Integer>() {
                public Integer call() throws Exception {
                    Thread.sleep(2000);
                    System.out.println("future task done......");
                    return 1;
                }
            });
            ListenableFuture<Boolean> transform = Futures.transform(task, new AsyncFunction<Integer, Boolean>() {
                public ListenableFuture<Boolean> apply(Integer integer) throws Exception {
                    return integer > 0 ? Futures.immediateFuture(Boolean.TRUE):
                            Futures.immediateFuture(Boolean.FALSE);
                }
            });
            System.out.println(transform.get());
            Thread.sleep(3000);
        }
    

    创建一个Future带值对象(非null)可以使用下面的接口

        public static <V> ListenableFuture<V> immediateFuture(@Nullable V value) {
    

    Conclusion

    Future在异步处理方面具有强大的功能,在分布式系统中组件异步通信,具有很好的应用。本文给出了Guava Future使用的几个实例,希望能对大家有所帮助。

    更多ListenableFuture接口可以参考官方API文档:
    < https://github.com/google/guava/wiki/ListenableFutureExplained >

  • 相关阅读:
    洛谷 P2148 [SDOI2009]E&D(SG函数入门)
    洛谷 P2197 【模板】nim游戏
    博弈整理
    洛谷 P2939 [USACO09FEB]改造路Revamping Trails(分层最短路二维dijs)
    洛谷 P3831 [SHOI2012]回家的路(最短路+分层图思想)
    BZOJ 2763 [JLOI2011]飞行路线(分层最短路)
    洛谷 P4016 负载平衡问题(费用流)
    洛谷 P1251 餐巾计划问题(费用流)
    把数组排成最小的数
    整数中1出现的次数(从1到n整数中1出现的次数)
  • 原文地址:https://www.cnblogs.com/jun-ma/p/4846839.html
Copyright © 2011-2022 走看看