EA Async 在 JVM 中實作 Async-Await 方法。它允許程式設計師以順序方式編寫非同步程式碼。
它很大程度上受到 .NET CLR 上的 Async-Await 的啟發,請參閱使用 Async 和 Await 進行非同步編程以獲取更多資訊。
EA Async 應用於編寫大量使用 CompletableFutures 或 CompletionStage 的非阻塞非同步程式碼。它透過在程式碼等待其他進程時釋放工作線程來提高可伸縮性;並透過使非同步程式碼更簡單、更具可讀性來提高生產力。
該專案由 Electronic Arts 開發,並根據 BSD 3-Clause License 獲得許可。
import static com . ea . async . Async . await ;
import static java . util . concurrent . CompletableFuture . completedFuture ;
public class Store
{
public CompletableFuture < Boolean > buyItem ( String itemTypeId , int cost )
{
if (! await ( bank . decrement ( cost ))) {
return completedFuture ( false );
}
await ( inventory . giveItem ( itemTypeId ));
return completedFuture ( true );
}
}
在此範例中, Bank.decrement
傳回CompletableFuture<Boolean>
, Inventory.giveItem
傳回CompletableFuture<String>
EA Async 重寫了對Async.await
調用,使您的方法成為非阻塞的。
這些方法看起來是阻塞的,但實際上會轉換為非同步方法,這些方法使用 CompletableFutures 在中間結果到達時繼續執行。
這是第一個範例在沒有 EA Async 的情況下的樣子。它的可讀性有點差。
import static java . util . concurrent . CompletableFuture . completedFuture ;
public class Store
{
public CompletableFuture < Boolean > buyItem ( String itemTypeId , int cost )
{
return bank . decrement ( cost )
. thenCompose ( result -> {
if (! result ) {
return completedFuture ( false );
}
return inventory . giveItem ( itemTypeId ). thenApply ( res -> true );
});
}
}
這是一個小例子......具有更多 CompletableFutures 的方法可能看起來非常複雜。
EA Async 抽象化了 CompletableFutures 的複雜性。
那你喜歡 CompletableFutures 嗎?嘗試將此方法轉換為僅使用 CompletableFutures 而不會阻塞(因此不會加入):
import static com . ea . async . Async . await ;
import static java . util . concurrent . CompletableFuture . completedFuture ;
public class Store
{
public CompletableFuture < Boolean > buyItem ( String itemTypeId , int cost )
{
if (! await ( bank . decrement ( cost ))) {
return completedFuture ( false );
}
try {
await ( inventory . giveItem ( itemTypeId ));
return completedFuture ( true );
} catch ( Exception ex ) {
await ( bank . refund ( cost ));
throw new AppException ( ex );
}
}
}
知道了?將其發送給我們。大概長得醜吧…
EA Async 目前支援 JDK 8-10。
它適用於 Java 和 Scala,並且應該適用於大多數 JVM 語言。使用 EA Async 的唯一要求是只能在傳回CompletableFuture
、 CompletionStage
或CompletableFuture
子類別的方法內部使用。
< dependency >
< groupId >com.ea.async</ groupId >
< artifactId >ea-async</ artifactId >
< version >1.2.3</ version >
</ dependency >
'com.ea.async:ea-async:1.2.3'
使用額外的 JVM 參數啟動您的應用程式: -javaagent:ea-async-1.2.3.jar
java -javaagent:ea-async-1.2.3.jar -cp your_claspath YourMainClass args...
建議將此作為預設選項新增至使用 ea-async 的 IntelliJ 專案中的啟動器。
在您的主課上或儘早致電至少一次:
Async.init();
如果您的 JVM 啟用了該功能,這將啟動執行時間偵測代理程式。如果您忘記呼叫此函數,則第一次呼叫await
將初始化系統(並列印警告)。
這是一個用於測試和開發的解決方案,它具有最少的配置。它可能會幹擾 JVM 偵錯。此替代方案作為後備方案存在。
ea-async-1.2.3.jar 是一個可運作的 jar,可以預先偵測您的檔案。
用法:
java -cp YOUR_PROJECT_CLASSPATH -jar ea-async-1.2.3.jar classDirectory
例子:
java -cp guava.jar ; commons-lang.jar -jar ea-async-1.2.3.jar target/classes
之後,目標/類別中的所有檔案都將被偵測。這些類別中不會留下對Async.await
和Async.init
的引用。
使用 ea-async-maven-plugin。它將在編譯時檢測您的類別並刪除對Async.await
和Async.init()
所有參考。
透過建置時檢測,您的專案使用者將不需要在其類別路徑中包含 EA Async,除非他們也選擇使用它。這意味著 EA Async不需要是傳遞依賴。
這是庫和 Maven 專案的最佳選擇。
< build >
< plugins >
< plugin >
< groupId >com.ea.async</ groupId >
< artifactId >ea-async-maven-plugin</ artifactId >
< version >1.2.3</ version >
< executions >
< execution >
< goals >
< goal >instrument</ goal >
< goal >instrument-test</ goal >
</ goals >
</ execution >
</ executions >
</ plugin >
</ plugins >
</ build >