Java非同期メソッド呼び出し

2968 ワード

多くの場合、私たちは時間のかかる方法を呼び出す必要がありますが、私たちはそれが実行されるのを待つ必要はありません.後の仕事を続ける必要はありません.ここで渋滞するのは時間の無駄です.では、私たちは解決する方法がありますか?あります!非同期で実行させます!
まず、非同期で実行されないスキームを見てみましょう.次は偽コードです.
//         1
longTimeMethod();
//         2

以上のように、longTimeMethodを実行する場合、このメソッドが完全に実行されるまで「実行するコード2」を実行する必要がありますが、両者の関連性がそれほど強くなければ、longTimeMethodの実行を待つ必要はありません.
では、非同期実行はどのようにして上記の問題を解決しますか?
  • マルチスレッドを使用してlongTimeMethodをマルチスレッドにカプセル化し、
  • を実行させる.
    Thread t = new Thread(){
      @Override
      public void run() {
        longTimeMethod();
      }
    };
    
  • Springの非同期方法で
  • を実行する
  • longTimeMethodをSpringの非同期メソッドにカプセル化します.このメソッドはSpring管理のクラスに必ず書きます.注記@Async
  • に注意してください.
    @Service
    public class AsynchronousService{
      @Async
      public void springAsynchronousMethod(){
        longTimeMethod();
      }
    }
    
  • 他のクラスはこのメソッドを呼び出します.ここでは、クラスで呼び出された場合、他のクラスは有効ではないことに注意してください.具体的には、Spring AOPの原理
  • を学ぶことができます.
    @Autowired
    private AsynchronousService asynchronousService;
    
    public void useAsynchronousMethod(){
      //         1
      asynchronousService.springAsynchronousMethod();
     //         2
    }
    

    では問題ですが、上記の非同期呼び出しの方法はいずれも戻り値がありません.戻り値がある場合、どのようにして戻り値を取得すればいいのでしょうか.
  • 非同期の書き方
  • //         1
    Integer result = longTimeMethod();
    //         2
    
  • JDK原生を採用したFuture類
  • //         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のインスタンスです.
  • Springの非同期方法で
  • を実行
  • longTimeMethodをSpringの非同期メソッドにカプセル化します.この非同期メソッドの戻り値はFutureのインスタンスです.この方法はSpring管理のクラスに必ず書き,注記@Asyncに注意する.
  • @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の例です.