Future

Future是代表一個非同步呼叫的回傳結果,而這個結果會在未來某一個時間點可以取得。這樣講有點抽象,那舉個例子好了,送洗衣服就是一個非同步的呼叫,因為衣服是交給別人洗而非自己洗,而洗好的衣服是一個未來會發生的結果,這個結果被Future這個class包裝起來。

我們再更具體一點的把它變成實際的程式碼,Future是一有一個型態參數的class,使用上大概會像這樣

Future<Clothes> future = laundryService.serviceAsync(myClothes);

洗衣店提供了一個非同步的服務,所以回傳一個Future代表的是非同步的結果(Asynchronous Result)。因為是非同步,所以這個method不會卡住。拿到這個future之後,我們可以選擇做別的事情,或是馬上blocking取得。

// block until result is available
Clothes clothes = future.get();

因為是非同步,所以我們可以一次執行很多個非同步的task,讓他們可以平行的去處理,最後再一次等所有的非同步結果。這在生活中也挺常發生,例如我去夜市買雞排豆花跟珍奶,我也不會呆呆的在每一個攤位前面等他一個一個做好,我可能會跟老闆說等等過來拿,讓這幾個攤位可以平行的處理我的tasks。

Future是一個interface,所以需要具體的實作。但通常不需要自己實作,還記得前面ThreadPool的章節就有提到Future了嗎? 事實上ExecutorService#submit就提供了一個非同步執行的實作,並且回傳一個Future,一般來講我們只要使用這個method來實作我們的非同步執行就可以了。

所以上面的程式碼的具體實作可能長這樣

public class LaundaryService {
    private ExecutorService executorService = /*...*/;

    public Future<Clothes> serviceAsync(Clothes dirtyClothes) {
        return executorService.submit(()-> service(dirtyClothes));
    }

    public Clothes service(Clothes dirtyClothes) {
        return dirtyClothes.wash();
    }
}

如此一來,這個LaundaryService當中有一個threadpool幫忙洗衣服,當呼叫serviceAsync,則會產生一個task在threadpool中執行,並且先回傳一個Future代表這個非同步的結果,就很像是一個取貨單一樣。caller在之後再透過future取得最後完成的結果。

results matching ""

    No results matching ""