Google Guava –期貨

這篇文章是我在Google Guava上的系列文章的延續,這次涵蓋了Future。 Futures類是用于使用Future / ListenableFuture接口的靜態實用程序方法的集合。 Future是提交給ExecutorService的異步任務(可運行或可調用)的句柄。 Future界面提供以下方法:獲取任務的結果,檢查任務是否完成或取消任務。 ListenableFuture接口擴展了Future接口,并添加了將完成偵聽器設置為在任務完成后運行的功能。 要創建ListenableFuture,您首先需要裝飾一個ExecutorService實例,如下所示:

ExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());

現在所有提交的Callables / Runnables將返回一個ListenableFuture。 MoreExecutors可以在com.google.common.util.concurrent包中找到。 ListenableFutures在覆蓋以前的帖子 。 期貨中有太多方法無法有效地涵蓋在一篇文章中,所以我只涉及:鏈,轉換,allAsList和successAsList。 在這篇文章中,我將交替使用Futures和ListenableFutures。

鏈方法返回一個ListenableFuture,其值是通過從輸入Future中獲取結果并將其作為參數應用到Function對象來計算的, Function對象又返回另一個ListenableFuture。 讓我們看一個代碼示例并逐步執行:

ListenableFuture<List<String>> indexSearch = luceneSearcher.searchAsync('firstName:martin');Function<List<String>, ListenableFuture<List<Person>>> queryFunction = new Function<List<String>, ListenableFuture<List<Person>>>() {@Overridepublic ListenableFuture<List<Person>> apply(final List<String> ids) {return dataService.getPersonsByIdAsync(ids);}};ListenableFuture<List<Person>> results = Futures.chain(indexSearch, queryFunction,executorService);
  1. 第1行正在使用Lucene執行異步搜索,并將返回一個ID列表,這些ID代表存儲在數據庫中的人員記錄的主鍵。 (我創建了一個小索引,其中存儲在Lucene中的唯一數據是id的數據,其余數據僅被索引了)。
  2. 第4 – 11行正在構建功能對象,其中apply方法將使用搜索未來的結果作為輸入。 apply返回的將來是對dataService對象的調用的結果。
  3. 第12行是從鏈調用返回的未來。 一旦輸入將來完成,將使用executorService運行該功能。

為了更加清楚,這是searchAsync和getPersonsByIdAsync方法的作用。 在前面的代碼示例中,這些方法調用分別來自第2行和第8行:

public ListenableFuture<List<String>> searchAsync(final String query)  {return executorService.submit(new Callable<List<String>>() {@Overridepublic List<String> call() throws Exception {return search(query);}});}public ListenableFuture<List<Person>> getPersonsByIdAsync(final List<String> ids) {return executorService.submit(new Callable<List<Person>>() {@Overridepublic List<Person> call() throws Exception {return getPersonsById(ids);}});}

chain方法具有兩個簽名:

  1. 鏈(ListentableFuture,函數)
  2. 鏈(ListenableFuture,函數,ExecutorService)

在確定使用哪種方法時,有幾點要考慮。
如果通過調用時間鏈完成了輸入將來,則所提供的函數將在調用線程中立即執行。 此外,如果未提供執行程序,則使用MoreExecutors.sameThreadExecutor。 MoreExecutors.sameThreadExecutor(顧名思義)位于ThreadPoolExecutor.CallerRunsPolicy之后,這意味著提交的任務在與執行/提交相同的線程中運行。

轉變

轉換方法類似于鏈式方法,因為它以Future和Function對象作為參數。 不同之處在于,不返回ListenableFuture,僅返回將給定功能應用于輸入future的結果。 考慮以下:

List<String> ids = ....
ListenableFuture<List<Map<String, String>>> dbRecords =   dataService.getPersonDataByIdAsync(ids);Function<List<Map<String, String>>,List<Person>> transformDbResults = new Function<List<String>, List<Person>>() {@Overridepublic List<Person> apply(List<Map<String, String>> personMapList) {List<Person> personObjList = new ArrayList<Person>();for(Map<String,String> personDataMap : personMapList){personObjList.add(new Person(personDataMap);} return personObjList;}};ListenableFuture<List<Person>> transformedResults = Futures.transform(dbRecords, transformDbResults, executorService);
  1. 在第2行上,執行異步數據庫查找
  2. 在第4行上,正在創建一個函數對象,但是在第8行上,請注意返回類型為List <Person>

transform方法具有與chain相同的重載方法調用,但有相同的警告。

AllAsList

allAsList方法將采用任意數量的ListenableFutures作為變量或以Iterator <ListenableFuture>的形式。 返回一個ListenableFuture,其值是所有輸入結果的列表。 列表中返回的值與原始列表的順序相同。 如果任何輸入值被取消或失敗,則返回的ListenableFuture也將被取消或失敗。 從allAsList調用取消返回的future不會傳播到列表中提交的任何原始任務。

ListenableFuture<List<Person>> lf1 = getPersonsByFirstNameFuture('martin');
ListenableFuture<List<Person>> lf2 = getPersonsByFirstNameFuture('bob');
ListenableFuture<List<List<Person>>> lfResults = Futures.allAsList(lf1, lf2);
//assume lf1 failed
List<List<Person>> personLists = lfResults.get() //call results in exception


成功名單

successAsList方法與allAsList非常相似,但是更加寬容。 就像allAsList一樣,successAsList返回結果列表的順序與輸入列表的順序相同,但是如果任何輸入失敗或被取消,則列表中的相應值將為null。 取消返回的將來也不會取消任何原始輸入。

ListenableFuture<List<Person>> lf1 = getPersonsByFirstNameFuture('martin');
ListenableFuture<List<Person>> lf2 = getPersonsByFirstNameFuture('bob');
ListenableFuture<List<List<Person>>> lfResults = Futures.successfulAsList(lf1, lf2);
//assume lf1 failed
List<List<Person>> personLists = lfResults.get();
List<Person> listOne = personLists.get(0) //listOne is null
List<Person> listTwo = personLists.get(1) //listTwo, not null


結論

希望這有助于發現Google Guava的Futures類中包含的有用性。 我創建了一個單元測試,以顯示本文中描述的方法的示例用法。 由于有大量支持代碼,因此我在gihub上創建了一個項目guava-blog 。 該項目還將包含我以前在Guava上發表的文章( Monitor , ListenableFuture )的源代碼。 一如既往地歡迎提出意見和建議。

資源資源

  • 番石榴項目首頁
  • 期貨API
  • 博客系列的源代碼


參考資料: Google Guava – JCG合作伙伴 Bill Bejeck的期貨,來自Random Thoughts On Coding博客。

翻譯自: https://www.javacodegeeks.com/2012/11/google-guava-futures.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/370721.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/370721.shtml
英文地址,請注明出處:http://en.pswp.cn/news/370721.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

iptables 配置后連接不上數據庫_Linux服務器配置-VSFTP服務配置(三)

上文&#xff1a;Linux服務器配置-VSFTP服務配置(二)一、vsftpd服務防火墻配置1、主動(POST)模式 FTP 防火墻配置CentOS6 系統 iptables 的配置iptables -t filter --line-number -nL INPUT#顯示現有防火墻規則&#xff0c;查看是否開啟20、21號端口。iptables -t filter -I IN…

下標索引必須為正整數類型或邏輯類型_Python3 基本數據類型

Python中的變量不需要聲明。每個變量在使用前都必須賦值&#xff0c;變量賦值以后該變量才會被創建。在Python中&#xff0c;變量就是變量&#xff0c;它沒有類型&#xff0c;我們所說的"類型"是變量所指的內存中對象的類型。Python 3中有六個標準的數據類型&#xf…

noip模擬賽 寫代碼

分析&#xff1a;這其實就是括號匹配題&#xff0c;一眼貪心題&#xff0c;不過一開始貪錯了&#xff0c;以為([)]是合法的......其實括號之間不能嵌套. 一開始的想法是盡量往左邊填左括號&#xff0c;因為每種括號的數量都確定了&#xff0c;那么左括號和右括號的數量也就確定…

[CF797C] Minimal string(貪心,棧)

題目鏈接&#xff1a;http://codeforces.com/contest/797/problem/C 題意&#xff1a;給個字符串&#xff0c;求字典序最小的出棧順序。 一開始想用優先隊列記錄全局最小的字符&#xff0c;然后每次入棧的時候檢查當前字符是不是最小的&#xff0c;如果是那么同時pop。這樣做的…

讓我們緊縮大數據

作為開發人員&#xff0c;我們的重點是簡單&#xff0c;有效的解決方案&#xff0c;因此&#xff0c;最有價值的原則之一就是“保持簡單和愚蠢”。 但是使用Hadoop map-reduce很難堅持這一點。 如果我們要評估多個Map Reduce作業中的數據&#xff0c;那么最終將得到與業務無關但…

行內元素和塊元素以及行內塊元素的特點

一、背景 初學html&#xff0c;接觸很多標簽 <h1>、<p>、<span>、<ul>、<em>等&#xff0c;當寫出簡單的小頁面的時候&#xff0c;例如僅僅是一篇帶有標題的文章&#xff0c;標題 <h1>標簽單獨一行&#xff0c;不管后面有多大的空間&…

軟件測試的功能測試和性能測試,大型軟件的功能測試流程及性能測試流程

大型軟件具有涉及子模塊繁多、建設過程復雜、功能全面、性能具有較高要求的特點。依據ISO/IEC 9126軟件產品評估標準&#xff0c;需要對軟件的功能性、可靠性、可用性、效率、可維護性、可移植性等方面進行評估。因此&#xff0c;需要有一種方法能夠對大型軟件進行測試&#xf…

vue 分模塊打包 腳手架_Vue面試官最愛的底層源碼問題,你可以這樣回答!

最近看到身邊很多人都在投簡歷&#xff0c;有因為企業裁員的&#xff0c;有因為自己想跳槽的&#xff0c;原因不一&#xff0c;但是最終大家都會需要接觸到面試這個事情。但是很多人對待面試不夠認真&#xff0c;只會等待結果&#xff0c;不去努力。所以這邊想整理一些懶人面試…

re.containerbase.startinternal 子容器啟動失敗_Python項目容器化實踐(二) Docker Machine和Docker Swarm...

前言這篇文章介紹Docker生態中的常被提到的Engine、Machine和Swarm&#xff0c;大家以了解為主&#xff0c;工作需要再深入。EngineDocker Engine其實就是我們常說的「Docker」&#xff0c;它是一個C/S模型(Client/Server)的應用&#xff0c;包含如下組件:Daemon。守護進程&…

基于設備樹的TQ2440的中斷(2)

下面以按鍵中斷為例看看基于設備數的中斷的用法&#xff1a; 設備樹&#xff1a; tq2440_key {compatible "tq2440,key";interrupt-parent <&gpf>;interrupts <0 IRQ_TYPE_EDGE_FALLING>, <1 IRQ_TYPE_EDGE_FALLING>;key_3 <&gpf 2…

計算機里有個不能進入的磁盤分區,新電腦只有一個分區怎么辦? 教你們如何不進pe給硬盤創建新分區!...

很多朋友新電腦剛買回來打開發現明明自己機械硬盤1T或者1T機械加128G固態&#xff0c;但是卻只有一個或者兩個分區&#xff0c;但是又不會分區現在教大家如何不用老毛桃大白菜之類的進pe系統里面就能直接創建新分區1 WinR輸入diskmgmt.msc2進入磁盤管理可以查看本機的C盤與E盤的…

OSGi中的權限

在上一篇文章中 &#xff0c;我們介紹了為Java應用程序實現沙箱的方法&#xff0c;在其中我們可以安全地運行移動代碼 。 這篇文章探討了如何在OSGi環境中執行相同的操作。 OSGi OSGi規范 為Java定義了一個動態模塊系統 。 因此&#xff0c;它是實施那種可以使您的應用程序動…

HTTP簡單教程

目錄 HTTP簡介 HTTP工作原理 HTTP消息結構 客戶端請求消息服務器響應消息實例 HTTP請求方法HTTP響應頭信息HTTP狀態碼 HTTP狀態碼分類HTTP狀態碼列表 HTTP content-type對照表 HTTP簡介 HTTP協議是Hyper Text Transfer Protocol&#xff08;超文本傳輸協議&#xff09;的縮寫&…

Reversed-Z詳解

在3D渲染管線中&#xff0c;Z這個家伙幾乎無處不在&#xff0c;如Z-Buffer&#xff0c;Early-Z&#xff0c;Z-Cull&#xff0c;Z-Test&#xff0c;Z-Write等等&#xff0c;稍有接觸圖形學的人都會對這些術語有所耳聞。 那么Z到底是什么呢&#xff1f;首先Z當然可以是任意坐標系…

pyqt開發的程序模板_小程序定制開發和模板開發要多少錢?有什么區別?

到現在&#xff0c;小程序開發已經有了1年多的歷史&#xff0c;已經達到百萬數量級。無論是小程序商城還是小程序游戲&#xff0c;其開發方式不外乎兩種&#xff0c;一種是定制開發&#xff0c;另一種是模板開發。對于很多初次接觸小程序的客戶來說&#xff0c;還不知道小程序的…

實現字符串的編碼轉換,用以解決字符串亂碼問題

引起亂碼的情況很多~實質上 主要是字符串本身的編碼格式 與程序所需要的編碼格式不一致導致的。要解決亂碼其實很簡單&#xff0c; 分2步 &#xff1a; 1&#xff1a;獲取到字符串 本身的編碼 2&#xff1a;改變字符串編碼 &#xff08;本身編碼 -> 新編碼&#xff09; 話不…

python運行原理_Python線程池及其原理和使用(超級詳細)

系統啟動一個新線程的成本是比較高的&#xff0c;因為它涉及與操作系統的交互。在這種情形下&#xff0c;使用線程池可以很好地提升性能&#xff0c;尤其是當程序中需要創建大量生存期很短暫的線程時&#xff0c;更應該考慮使用線程池。 線程池在系統啟動時即創建大量空閑的線程…

Google Guava緩存

這篇文章是我在Google Guava上系列文章的續篇&#xff0c;這次涵蓋了Guava Cache。 與HashMap或ConcurrentHashMap相比&#xff0c;Guava Cache提供了更大的靈活性和功能&#xff0c;但不像使用EHCache或Memcached那樣繁重&#xff08;就此而言&#xff0c;它很健壯&#xff0c…

html 三列布局(兩列自適應,一列固定寬度)

不做過多解釋&#xff1a;主要是記錄一個完整的布局樣式&#xff0c;實現頁面大致三列其中左右兩列是自適應寬度&#xff0c;中間固定寬度效果。 不多少代碼奉上&#xff1a; CSS樣式代碼&#xff1a; /*********************公共標簽樣式********************//************…

jsp常用動作

jsp:include 動態包含&#xff1b; jsp:forward 轉發&#xff1b; jsp:useBean 實例化bean對象&#xff1b; jsp:setProperty 設置一個屬性值 jsp:getProperty 獲取一個屬性值 jsp:param 動態傳參數&#xff1b; jsp:plugin 生成一個插件 jsp:useBean 實例化一個對象…