番石榴的ListenableFuture
Guava中的ListenableFuture試圖為Future對象定義一致的API,以注冊完成回調。 通過在Future完成時添加回調的功能,我們可以異步有效地響應傳入的事件。 如果您的應用程序與許多將來的對象高度并發,我強烈建議您盡可能使用ListenableFuture 。 從技術上講, ListenableFuture通過添加以下簡單ListenableFuture擴展了Future接口:
方法。 而已。 如果掌握了ListenableFuture ,則可以注冊Runnable以在有問題的將來完成時立即執行。 您還必須提供將用于執行您的偵聽Executor ( ExecutorService擴展)–這樣長時間運行的偵聽器不會占用您的工作線程。
讓我們付諸行動。 我們將從重構我們的第一個Web ListenableFuture 器示例以使用ListenableFuture 。 幸運的是,在線程池的情況下,只需使用MoreExecutors.listeningDecorator()將它們包裝起來MoreExecutors.listeningDecorator() :
ListeningExecutorService pool = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));for (final URL siteUrl : topSites) {final ListenableFuture<String> future = pool.submit(new Callable<String>() {@Overridepublic String call() throws Exception {return IOUtils.toString(siteUrl, StandardCharsets.UTF_8);}});future.addListener(new Runnable() {@Overridepublic void run() {try {final String contents = future.get();//...process web site contents} catch (InterruptedException e) {log.error("Interrupted", e);} catch (ExecutionException e) {log.error("Exception in task", e.getCause());}}}, MoreExecutors.sameThreadExecutor()); }有幾個有趣的發現。 首先,請注意ListeningExecutorService如何包裝現有的Executor 。 這類似于ExecutorCompletionService方法 。 稍后,我們注冊自定義Runnable ,以便在每個任務完成時得到通知。 其次,請注意錯誤處理變得多么丑陋:我們必須處理InterruptedException (從技術上講,這應該永遠不會發生,因為Future已經解決,并且get()永遠不會拋出它)和ExecutionException 。 我們還沒有介紹,但是Future<T>必須以某種方式處理異步計算期間發生的異常。 此類異常包含在從get()引發的ExecutionException (因此在記錄期間調用getCause() get() 。
最后請注意正在使用MoreExecutors.sameThreadExecutor() 。 這是一個方便的抽象,您可以使用每API一些想要使用的時間Executor / ExecutorService (大概線程池),而你的罰款使用當前線程。 這在單元測試期間特別有用–即使您的生產代碼使用異步任務,在測試期間您也可以從同一線程運行所有內容。
不管它多么方便,整個代碼看起來都有些混亂。 幸運的是,在夢幻般的Futures類中有一個簡單的實用程序方法:
Futures.addCallback(future, new FutureCallback<String>() {@Overridepublic void onSuccess(String contents) {//...process web site contents}@Overridepublic void onFailure(Throwable throwable) {log.error("Exception in task", throwable);} });FutureCallback是一個更簡單的抽象方法,可以解決將來的問題并為您執行異常處理。 如果需要,您仍然可以為偵聽器提供自定義線程池。 如果您仍然使用一些仍會返回Future舊式API,則可以嘗試JdkFutureAdapters.listenInPoolThread() ,它是將普通Future<V>轉換為ListenableFuture<V>的適配器。 但是請記住,一旦開始使用addListener() ,每個這樣的適配器將只需要一個線程即可工作,因此此解決方案根本無法擴展,因此應避免使用它。
Future<String> future = //... ListenableFuture<String> listenableFuture =JdkFutureAdapters.listenInPoolThread(future); 一旦了解了基礎知識,我們就可以深入探究聽期貨的最大優勢: 轉型和連鎖 。 這是高級材料,已被警告。
參考: NoBlogDefFound博客中來自JCG合作伙伴 Tomasz Nurkiewicz的番石榴中的ListenableFuture 。
翻譯自: https://www.javacodegeeks.com/2013/02/listenablefuture-in-guava.html
總結
以上是生活随笔為你收集整理的番石榴的ListenableFuture的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信里面的零钱为什么不能买理财?
- 下一篇: 理财风险有没有可能本金都拿不回来?