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 >


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM