Java非同期メソッド呼び出し
2968 ワード
多くの場合、私たちは時間のかかる方法を呼び出す必要がありますが、私たちはそれが実行されるのを待つ必要はありません.後の仕事を続ける必要はありません.ここで渋滞するのは時間の無駄です.では、私たちは解決する方法がありますか?あります!非同期で実行させます!
まず、非同期で実行されないスキームを見てみましょう.次は偽コードです.
以上のように、longTimeMethodを実行する場合、このメソッドが完全に実行されるまで「実行するコード2」を実行する必要がありますが、両者の関連性がそれほど強くなければ、longTimeMethodの実行を待つ必要はありません.
では、非同期実行はどのようにして上記の問題を解決しますか?マルチスレッドを使用してlongTimeMethodをマルチスレッドにカプセル化し、 を実行させる. Springの非同期方法で を実行する longTimeMethodをSpringの非同期メソッドにカプセル化します.このメソッドはSpring管理のクラスに必ず書きます.注記@Async に注意してください.他のクラスはこのメソッドを呼び出します.ここでは、クラスで呼び出された場合、他のクラスは有効ではないことに注意してください.具体的には、Spring AOPの原理 を学ぶことができます.
では問題ですが、上記の非同期呼び出しの方法はいずれも戻り値がありません.戻り値がある場合、どのようにして戻り値を取得すればいいのでしょうか.非同期の書き方 JDK原生を採用したFuture類
longTimeMethod 2を呼び出してFutureオブジェクトを返します(ここでのlongTimeMethod 2はもちろん上のlongTimeMethodではありません)、「実行するコード2が必要です」を処理し、結果を返す必要があるときにfuture.get()を直接呼び出すと戻り値が得られます.次にlongTimeMethod 2がどのように実現されるかを見てみましょう.
スレッドプールを使用して、タスクをスレッドプールに追加し、Futureオブジェクトを返すことができます.実はlongTimeMethod 2を呼び出す方法は、他のスレッドを開き、他のスレッドが呼び出されています.
Futureでは,無参のget()メソッドのほかに,参のあるget()メソッドがある.パラメータ付きget()メソッドに入力されるパラメータは、待機時間、すなわちタイムアウト設定であり、ずっと待つ必要はありません.我々が返すFutureオブジェクトはFutureTaskのインスタンスです. Springの非同期方法で を実行 longTimeMethodをSpringの非同期メソッドにカプセル化します.この非同期メソッドの戻り値はFutureのインスタンスです.この方法はSpring管理のクラスに必ず書き,注記@Asyncに注意する. 他のクラスはこのメソッドを呼び出します.ここでは、クラスで呼び出された場合、他のクラスは有効ではないことに注意してください.
実はSpringは原生のFutureでカプセル化されただけで、私たちが最終的に得たのはFutureの例です.
まず、非同期で実行されないスキームを見てみましょう.次は偽コードです.
// 1
longTimeMethod();
// 2
以上のように、longTimeMethodを実行する場合、このメソッドが完全に実行されるまで「実行するコード2」を実行する必要がありますが、両者の関連性がそれほど強くなければ、longTimeMethodの実行を待つ必要はありません.
では、非同期実行はどのようにして上記の問題を解決しますか?
Thread t = new Thread(){
@Override
public void run() {
longTimeMethod();
}
};
@Service
public class AsynchronousService{
@Async
public void springAsynchronousMethod(){
longTimeMethod();
}
}
@Autowired
private AsynchronousService asynchronousService;
public void useAsynchronousMethod(){
// 1
asynchronousService.springAsynchronousMethod();
// 2
}
では問題ですが、上記の非同期呼び出しの方法はいずれも戻り値がありません.戻り値がある場合、どのようにして戻り値を取得すればいいのでしょうか.
// 1
Integer result = longTimeMethod();
// 2
// 1
Future future = longTimeMethod2();
// 2
Integer result = future.get();
longTimeMethod 2を呼び出してFutureオブジェクトを返します(ここでのlongTimeMethod 2はもちろん上のlongTimeMethodではありません)、「実行するコード2が必要です」を処理し、結果を返す必要があるときにfuture.get()を直接呼び出すと戻り値が得られます.次にlongTimeMethod 2がどのように実現されるかを見てみましょう.
private Future longTimeMethod2() {
//
ExecutorService threadPool = Executors.newCachedThreadPool();
// Future
Future future = threadPool.submit(new Callable() {
@Override
public Integer call() throwsException {
return longTimeMethod();
}
});
return future;
}
スレッドプールを使用して、タスクをスレッドプールに追加し、Futureオブジェクトを返すことができます.実はlongTimeMethod 2を呼び出す方法は、他のスレッドを開き、他のスレッドが呼び出されています.
Futureでは,無参のget()メソッドのほかに,参のあるget()メソッドがある.パラメータ付きget()メソッドに入力されるパラメータは、待機時間、すなわちタイムアウト設定であり、ずっと待つ必要はありません.我々が返すFutureオブジェクトはFutureTaskのインスタンスです.
@Service
public class AsynchronousService{
@Async
public Future springAsynchronousMethod(){
Integer result = longTimeMethod();
return new AsyncResult(result);
}
}
@Autowired
private AsynchronousService asynchronousService;
public void useAsynchronousMethod(){
Future future = asynchronousService.springAsynchronousMethod();
future.get(1000, TimeUnit.MILLISECONDS);
}
実はSpringは原生のFutureでカプセル化されただけで、私たちが最終的に得たのはFutureの例です.