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 >

  • 相关阅读:
    [BZOJ]4810: [Ynoi2017]由乃的玉米田
    VK Cup 2017
    Educational Codeforces Round 19
    [BZOJ]4162: shlw loves matrix II
    2017-4-14校内训练
    第一次 CSP-S 的游记
    APIO2009 采油区域
    NOIP2017 逛公园
    NOIP2013 货车运输
    【9018:1458】征兵
  • 原文地址:https://www.cnblogs.com/jun-ma/p/4846839.html
Copyright © 2011-2022 走看看