天天看點

guava中的ListenableFuture

ListenableFuture還有其他幾種内置實作:

  1. SettableFuture:不需要實作一個方法來計算傳回值,而隻需要傳回一個固定值來做為傳回值,可以通過程式設定此Future的傳回值或者異常資訊
  2. CheckedFuture: 這是一個繼承自ListenableFuture接口,他提供了checkedGet()方法,此方法在Future執行發生異常時,可以抛出指定類型的異常。

SettableFuture

AbstractFuture抽象類實作了ListenableFuture接口,是以SettableFuture類也是ListenableFuture接口的一種實作,源碼相當的簡單,其中隻包含了三個方法:

      1、一個用于建立SettableFuture執行個體的靜态create()方法;

      2、set方法用于設定Future的值,傳回是否設定成功,如果Future的值已經被設定或任務被取消,會傳回false;

      3、setException與set方法類似,用于設定Future傳回特定的異常資訊,傳回exception是否設定成功。

 SettableFuture類是ListenableFuture接口的一種實作,我們可以通過SettableFuture設定Future的傳回 值,或者設定Future傳回特定的異常資訊,可以通過SettableFuture内部提供的靜态方法create()建立一個 SettableFuture執行個體,下面是一個簡單的例子:

SettableFuture sf = SettableFuture.create();
//設定成功後傳回指定的資訊
sf.set("SUCCESS");
//設定失敗後傳回特定的異常資訊
sf.setException(new RuntimeException("Fails"));
           

     通過上面的例子,我們看到,通過create()方法,我們可以建立一個預設的ettableFuture執行個體,當我們需要為Future執行個體設定一個返 回值時,我們可以通過set方法,設定的值就是Future執行個體在執行成功後将要傳回的值;另外,當我們想要設定一個異常導緻Future執行失敗,我們 可以通過調用setException方法,我們将給Future執行個體設定指定的異常傳回。當我們有一個方法傳回Future執行個體時,SettableFuture會顯得更有價值,但是已經有了Future的傳回值,我們也不需要再去執行異步任 務擷取傳回值。

AsyncFunction

接口傳回的是 ListenableFuture,當我們需要接收AsyncFunction轉換後的結果時,我們需要調用 ListenableFuture.get()方法。

AsyncFunction接口常被用于當我們想要異步的執行轉換而不造成線程阻塞時,盡管Future.get()方法會在任務沒有完成時造成阻塞,但 是AsyncFunction接口并不被建議用來異步的執行轉換,它常被用于傳回Future執行個體,我們來看下面的代碼示例:

class AsyncFunctionSample implements
        AsyncFunction<Long, String> {
    private ConcurrentMap<Long, String> map = Maps.newConcurrentMap();
    private ListeningExecutorService listeningExecutorService;
    //這裡簡單的模拟一個service
    private Map<Long,String> service = new HashMap<Long, String>(){
        {
            put(,"retrieved");
        }
    };

    @Override
    public ListenableFuture<String> apply(final Long input) throws
            Exception {
        if (map.containsKey(input)) {
            SettableFuture<String> listenableFuture = SettableFuture.
                    create();
            listenableFuture.set(map.get(input));
            return listenableFuture;
        } else {
            return listeningExecutorService.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    //service中通過input擷取retrieved
                    String retrieved = service.get(input);
                    map.putIfAbsent(input, retrieved);
                    return retrieved;
                }
            });
        }
    }
}
           

上面的例子是對AsyncFunction接口的一個簡單實作,内部包含了ConcurrentHashMap的執行個體,當我們調用apply方法的時候, 我們會首先在我們的map中查詢value值,傳入的input對象充當了一個關鍵的key,如果我們在map中找到了相應的value值,我們使用 SettableFuture對象建立了一個Future對象,并且設定傳回值等于從map中擷取到的value值;否則的話,我們通過向 ExecutorService送出Callable傳回Future對象,同樣的,在相應的map中,為相應的key設定擷取到的value值。