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 >

原文地址:https://www.cnblogs.com/jun-ma/p/4846839.html