EA Async は、JVM に Async-Await メソッドを実装します。これにより、プログラマは非同期コードを逐次的に作成できます。
これは、.NET CLR の Async-Await から大きく影響を受けています。詳細については、「Async と Await を使用した非同期プログラミング」を参照してください。
CompletableFutures または CompletionStage を多用するノンブロッキングの非同期コードを作成するには、EA Async を使用する必要があります。コードが他のプロセスを待機している間にワーカー スレッドを解放することで、スケーラビリティが向上します。また、非同期コードをよりシンプルで読みやすくすることで生産性が向上します。
このプロジェクトはエレクトロニック アーツによって開発され、BSD 3 条項ライセンスに基づいてライセンス供与されています。
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 非同期を使用しない場合の最初の例は次のようになります。少し読みにくくなります。
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 );
});
}
}
これは小さな例です...さらにいくつかの CompletableFuture を含むメソッドは、非常に複雑に見える可能性があります。
EA Async は、CompletableFuture の複雑さを抽象化します。
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 プロジェクトのランチャーにデフォルトのオプションとして追加することをお勧めします。
メインクラスまたはできるだけ早い段階で、少なくとも 1 回呼び出します。
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 を含める必要がなくなります。これは、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 >