Java異步編程工具Twitter?Future詳解
異步編程(Twitter Future)
為啥要異步
異步編程有點(diǎn)難以理解,這東西感覺不符合常理,因?yàn)槲覀兯伎级际前凑沾械倪壿?,事都是一件一件辦。但在異步計(jì)算的情況下,回調(diào)往往分散在代碼片段中,需要理解其中的意義。
最難搞的就是組合,嵌套。如果再加上遞歸,派發(fā)等邏輯,能寫的極其復(fù)雜,又難以理解。當(dāng)我們需要處理其中一個(gè)步驟中可能發(fā)生的錯(cuò)誤時(shí),情況會(huì)變得更糟。
java在核心庫(kù)中引入了CompletableFuture,同時(shí)也是一個(gè)異步框架,有大約50種不同的方法用于組合、組合和執(zhí)行異步計(jì)算步驟以及處理錯(cuò)誤。
基本用法
1、封裝計(jì)算邏輯,異步返回。
CompletableFuture的靜態(tài)方法runAsync和supplySync允許我們相應(yīng)地使用Runnable和SupplySync函數(shù)類型創(chuàng)建一個(gè)完整的future實(shí)例。如下就是一個(gè)簡(jiǎn)單的示例。
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)異步處理
如果想在一個(gè)future完畢后,接上另一個(gè)異步任務(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、并行多個(gè)異步任務(wù),統(tǒng)一等待結(jié)果
當(dāng)我們需要并行執(zhí)行多個(gè)Future時(shí),我們通常希望等待所有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、異步錯(cuò)誤處理
CompletableFuture類不需要捕獲語(yǔ)法塊中的異常,而是允許我們用一種特殊的回調(diào)方法來(lái)處理。此方法接收兩個(gè)參數(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包裝
對(duì)于以上的代碼,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、并行多個(gè)異步任務(wù)
這個(gè)相對(duì)看起來(lái)就簡(jiǎn)潔的多了,用List添加所有的異步結(jié)果,然后collect收集起來(lái),調(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、錯(cuò)誤處理
這部分處理也比較簡(jiǎn)潔,注意這里返回的是BoxedUnit.UNIT,其實(shí)這是scala的語(yǔ)法,可以理解成void的return。
future.onFailure(new Function1<Throwable, BoxedUnit>() {
@Override
public BoxedUnit apply(Throwable v1)
{
System.out.println("Error");
return BoxedUnit.UNIT;
}
);其他用法
除了以上的用法。其實(shí)還有很多用法。
例如:collectToTry,會(huì)返回一個(gè)Try對(duì)象,Try代表了一個(gè)成功返回的結(jié)果,或者錯(cuò)誤返回的異常.
可以使用try.isReturn()?來(lái)判斷是否是正常返回的。這在多個(gè)Future異步結(jié)果的處理中用著很?不錯(cuò)。
Future<List<Try<String>>> futures = Futures.collectToTry(futureList);
flattern(),該方法類似scala的扁平方法,可以將嵌套的異步對(duì)象拍平。
flatMap(),和flatMap的用法一致,不過是異步的結(jié)果。
當(dāng)你用不好twitter future的時(shí)候,隨時(shí)隨地可以轉(zhuǎn)成javaFuture。 toJavaFuture()。所以,放心用。
其他更有趣的方法,可以自己研究下,還是有點(diǎn)騷東西的。
其他工具
twitter的這個(gè)工具包出了異步編程外,還有其他的很實(shí)用的工具。 包括:
codec編解碼cahce緩存hasing哈希相關(guān)jacksonmockthirftvalidator
自行發(fā)掘吧。 地址是: github.com/twitter/uti…
到此這篇關(guān)于Java異步編程工具Twitter Future詳解的文章就介紹到這了,更多相關(guān)Java異步編程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring?Boot?使用?SSE?方式向前端推送數(shù)據(jù)詳解
這篇文章主要介紹了Spring?Boot?使用SSE方式向前端推送數(shù)據(jù)詳解,SSE簡(jiǎn)單的來(lái)說就是服務(wù)器主動(dòng)向前端推送數(shù)據(jù)的一種技術(shù),它是單向的,也就是說前端是不能向服務(wù)器發(fā)送數(shù)據(jù)的2022-08-08
springboot項(xiàng)目或其他項(xiàng)目使用@Test測(cè)試項(xiàng)目接口配置
這篇文章主要介紹了springboot項(xiàng)目或其他項(xiàng)目使用@Test測(cè)試項(xiàng)目接口配置,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
Java基于中介者模式實(shí)現(xiàn)多人聊天室功能示例
這篇文章主要介紹了Java基于中介者模式實(shí)現(xiàn)多人聊天室功能,詳細(xì)分析了中介者模式的概念、原理以及使用中介模式實(shí)現(xiàn)多人聊天的步驟、操作技巧與注意事項(xiàng),需要的朋友可以參考下2018-05-05
Springboot?引入?Redis?并配置序列化并封裝RedisTemplate?
這篇文章主要介紹了Springboot?引入?Redis?并配置序列化并封裝RedisTemplate。文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09
SpringCloud連接不上遠(yuǎn)程N(yùn)acos問題排查
本文主要介紹了SpringCloud連接不上遠(yuǎn)程N(yùn)acos問題排查,可能是因?yàn)槲撮_放端口,或集群內(nèi)部通信異常等,下面就來(lái)介紹一下問題解決,感興趣的可以了解一下2024-06-06
springmvc @RequestBody String類型參數(shù)的使用
這篇文章主要介紹了springmvc @RequestBody String類型參數(shù)的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
使用jmeter實(shí)現(xiàn)對(duì)jar包的調(diào)用方式
這篇文章主要介紹了使用jmeter實(shí)現(xiàn)對(duì)jar包的調(diào)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
使用Java實(shí)現(xiàn)簡(jiǎn)單串口通信
這篇文章主要介紹了使用Java實(shí)現(xiàn)簡(jiǎn)單串口通信,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
Spring-Validation 后端數(shù)據(jù)校驗(yàn)的實(shí)現(xiàn)
這篇文章主要介紹了Spring-Validation 后端數(shù)據(jù)校驗(yàn)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07

