Java異步編程工具Twitter?Future詳解
異步編程(Twitter Future)
為啥要異步
異步編程有點(diǎn)難以理解,這東西感覺不符合常理,因?yàn)槲覀兯伎级际前凑沾械倪壿嫞露际且患患k。但在異步計(jì)算的情況下,回調(diào)往往分散在代碼片段中,需要理解其中的意義。
最難搞的就是組合,嵌套。如果再加上遞歸,派發(fā)等邏輯,能寫的極其復(fù)雜,又難以理解。當(dāng)我們需要處理其中一個步驟中可能發(fā)生的錯誤時,情況會變得更糟。
java在核心庫中引入了CompletableFuture,同時也是一個異步框架,有大約50種不同的方法用于組合、組合和執(zhí)行異步計(jì)算步驟以及處理錯誤。
基本用法
1、封裝計(jì)算邏輯,異步返回。
CompletableFuture的靜態(tài)方法runAsync
和supplySync
允許我們相應(yīng)地使用Runnable和SupplySync函數(shù)類型創(chuàng)建一個完整的future實(shí)例。如下就是一個簡單的示例。
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(3 * 1000); } catch (InterruptedException e) { throw new RuntimeException(e); } return "Hello"; }); System.out.println("Main goes on..."); String result = future.get(); System.out.println(result);
如上代碼片段,打印后的結(jié)果是Main goes on 先執(zhí)行,異步任務(wù)在future.get() 阻塞結(jié)果返回。
2、異步計(jì)算結(jié)果串聯(lián)異步處理
如果想在一個future完畢后,接上另一個異步任務(wù),則用法如下:
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> { try { System.out.println("task1: " + Thread.currentThread().getName()); Thread.sleep(2 * 1000); } catch (InterruptedException e) { throw new RuntimeException(e); } return "Hello"; }); CompletableFuture<String> future = completableFuture.thenApply(s -> { try { System.out.println("task2: " + Thread.currentThread().getName()); Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } return s + " World"; }); System.out.println(future.get());
3、并行多個異步任務(wù),統(tǒng)一等待結(jié)果
當(dāng)我們需要并行執(zhí)行多個Future時,我們通常希望等待所有Futrue都能夠執(zhí)行,然后處理它們的全部統(tǒng)一的返回結(jié)果。
CompletableFuture 的 allOf
靜態(tài)方法允許等待所有的future完成:
如下面的代碼片段:
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello"); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "my"); CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> "World"); CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future1, future2, future3); combinedFuture.get(); System.out.println(future1.isDone()); System.out.println(future2.isDone()); System.out.println(future3.isDone());
4、異步錯誤處理
CompletableFuture類不需要捕獲語法塊中的異常,而是允許我們用一種特殊的回調(diào)方法來處理。此方法接收兩個參數(shù):計(jì)算結(jié)果
(如果成功完成)和異常結(jié)果
(如果某些計(jì)算步驟有異常)。
String name = "fengkai CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> { if ("fengkai".equals(name)) { throw new RuntimeException("Computation error!"); } return "Hello, " + name; }).handle((s, t) -> s != null ? s : "Hello, Stranger!"); System.out.println(completableFuture.get());
Twitter包裝
對于以上的代碼,twitter工具包有自己的小包裝,可以提升一點(diǎn)編程的逼格。
以下是用法:
pom依賴
首先引入maven坐標(biāo),因?yàn)槭怯胹cala編寫的工具包,所以要引入scala的依賴。
<dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> <version>${scala.version}</version> </dependency> <dependency> <groupId>com.twitter</groupId> <artifactId>util-core_2.12</artifactId> <version>${twitter.util.version}</version> </dependency>
1、封裝計(jì)算邏輯,異步返回
注意這里的FuturePool,可以用ExecutorService去包裝。
Future<String> future = futurePool.apply(() -> { try { Thread.sleep(3 * 1000); } catch (InterruptedException e) { throw new RuntimeException(e); } return "Hello"; })
2、異步計(jì)算結(jié)果串聯(lián)異步處理
和CompletableFuture
相似的,有以下用法,不過是用的map方法
Future<String> future = futurePool.apply(() -> { try { System.out.println("task2: " + Thread.currentThread().getName()); Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } return "Hello"; }); Future<Object> mappedFuture = future.map(new Function1<String, Object>() { @Override public Object apply(String v1) { try { System.out.println("task2: " + Thread.currentThread().getName()); Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } return "World"; } }); Await.result(mappedFuture);
3、并行多個異步任務(wù)
這個相對看起來就簡潔的多了,用List
添加所有的異步結(jié)果,然后collect
收集起來,調(diào)用get()
或者其他方法阻塞等待。
List<Future> futures = new ArrayList<>(); Future<String> future1 = futurePool.apply(() -> "hello"); Future<String> future2 = futurePool.apply(() -> "my"); Future<String> future3 = futurePool.apply(() -> "world"); futures.add(future1); futures.add(future2); futures.add(future3); Future<List<String>> collect = Futures.collect(futureList);
4、錯誤處理
這部分處理也比較簡潔,注意這里返回的是BoxedUnit.UNIT
,其實(shí)這是scala的語法,可以理解成void
的return
。
future.onFailure(new Function1<Throwable, BoxedUnit>() { @Override public BoxedUnit apply(Throwable v1) { System.out.println("Error"); return BoxedUnit.UNIT; } );
其他用法
除了以上的用法。其實(shí)還有很多用法。
例如:collectToTry
,會返回一個Try對象,Try代表了一個成功返回的結(jié)果,或者錯誤返回的異常.
可以使用try.isReturn()?來判斷是否是正常返回的。這在多個Future異步結(jié)果的處理中用著很?不錯。
Future<List<Try<String>>> futures = Futures.collectToTry(futureList);
flattern()
,該方法類似scala的扁平方法,可以將嵌套的異步對象拍平。
flatMap()
,和flatMap的用法一致,不過是異步的結(jié)果。
當(dāng)你用不好twitter future的時候,隨時隨地可以轉(zhuǎn)成javaFuture。 toJavaFuture()
。所以,放心用。
其他更有趣的方法,可以自己研究下,還是有點(diǎn)騷東西的。
其他工具
twitter的這個工具包出了異步編程外,還有其他的很實(shí)用的工具。 包括:
codec
編解碼cahce
緩存hasing
哈希相關(guān)jackson
mock
thirft
validator
自行發(fā)掘吧。 地址是: github.com/twitter/uti…
到此這篇關(guān)于Java異步編程工具Twitter Future詳解的文章就介紹到這了,更多相關(guān)Java異步編程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis如何實(shí)現(xiàn)多表查詢(多對一、一對多)
這篇文章主要給大家介紹了關(guān)于MyBatis如何實(shí)現(xiàn)多表查詢(多對一、一對多)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05Java(springboot) 讀取txt文本內(nèi)容代碼實(shí)例
這篇文章主要介紹了Java(springboot) 讀取txt文本內(nèi)容代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-02-02Java那點(diǎn)事——StringBuffer與StringBuilder原理與區(qū)別
本文給大家分享StringBuffer與StringBuilder的區(qū)別,它們的應(yīng)用場景是什么?非常不錯,面試考官經(jīng)??嫉囊粋€問題,有需要的朋友跟著腳本之家小編一起學(xué)習(xí)吧2016-06-06java使用MulticastSocket實(shí)現(xiàn)基于廣播的多人聊天室
這篇文章主要為大家詳細(xì)介紹了java使用MulticastSocket實(shí)現(xiàn)基于廣播的多人聊天室,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-01-01java接口返回參數(shù)按照請求參數(shù)進(jìn)行排序方式
這篇文章主要介紹了java接口返回參數(shù)按照請求參數(shù)進(jìn)行排序方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09Java關(guān)鍵字finally_動力節(jié)點(diǎn)Java學(xué)院整理
java關(guān)鍵字finally不管是否出現(xiàn)異常,finally子句總是在塊完成之前執(zhí)行。下面通過實(shí)現(xiàn)代碼給大家介紹Java關(guān)鍵字finally相關(guān)知識,需要的的朋友參考下吧2017-04-04Java中使用ConcurrentHashMap實(shí)現(xiàn)線程安全的Map
在Java中,ConcurrentHashMap是一種線程安全的哈希表,可用于實(shí)現(xiàn)多線程環(huán)境下的Map操作。它支持高并發(fā)的讀寫操作,通過分段鎖的方式實(shí)現(xiàn)線程安全,同時提供了一些高級功能,比如迭代器弱一致性和批量操作等。ConcurrentHashMap在高并發(fā)場景中具有重要的應(yīng)用價值2023-04-04