2017-02-01 1 views
0


私はAPIを開発中です。このAPIは結果を得るために2つのDBクエリを実行する必要があります。コントローラーでの戻り値の型として呼び出し可能に使用され
Spring 4で並列スレッドを実行するための洗練された方法


  • は、私は、次の戦略を試してみました。
  • 2つのクエリを並行して実行し、終了時刻を検出するために、2つのスレッド(CallableとCoundownLatchを使用)を作成しました。

    public class PetService { 
        public Object getData() { 
         CountDownLatch latch = new CountDownLatch(2); 
         AsyncQueryDBTask<Integer> firstQuery= new AsyncQueryDBTask<>(latch); 
         AsyncQueryDBTask<Integer> secondQuery= new AsyncQueryDBTask<>(latch); 
         latch.await(); 
    } 
    
    public class AsyncQueryDBTask<T> implements Callable { 
    
        private CountDownLatch latch; 
    
        public AsyncQueryDBTask(CountDownLatch latch) { this.latch = latch;} 
    
        @Override 
        public T call() throws Exception { 
        //Run query 
        latch.countDown(); 
        } 
    

それはうまく働いたが、私はどこかで春の構造を壊すだと感じています。

は、私は - どのように独自のクエリを実行する2つのスレッドの両方を知って自分の仕事を完了し
春4にデータを取得するための最も効率的な方法は何だろうか?
- スレッドリソースの使用や解放などの制御方法

ありがとうございます。

+1

https://www.mkyong.com/spring/spring-and-java-thread-example/ – StanislavL

答えて

4

通常、ApplicationServerで独自のスレッドを作成したり、スレッドのライフサイクルを管理したりすることは望ましくありません。アプリケーションサーバーでは、ExecutorServiceにタスクを送信して、バックグラウンドワーカースレッドをプールできます。

便利なことに、Springには、すべての内容を処理する@Asyncアノテーションがあります。あなたがThreadPoolTaskExecutorを設定し、春はあなたのためのタスクを送信する処理する、非同期メソッドを有効に限り

public class PetService { 
    public Object getData() { 
     Future<Integer> futureFirstResult = runFirstQuery(); 
     Future<Integer> futureSecondResult = runSecondQuery(); 

     Integer firstResult = futureFirstResult.get(); 
     Integer secondResult = futureSecondResult.get(); 
    } 

    @Async 
    public Future<Integer> runFirstQuery() { 
     //do query 
     return new AsyncResult<>(result); 
    } 

    @Async 
    public Future<Integer> runSecondQuery() { 
     //do query 
     return new AsyncResult<>(result); 
    } 
} 

:あなたの例では、未来を返す2つの非同期メソッドを作成します。

注:get()メソッドは、結果がワーカースレッドによって返されるまで現在のスレッドをブロックしますが、他のワーカースレッドはブロックしません。一般的には、永久にブロックされないようにタイムアウトを設定することをお勧めします。

+0

あなたの答えをありがとう。本当に役に立ちます。 もう一度お手伝いしてください。 '' 'java リストl =新しいArrayList(); l.add(future1.get()); l.add(future2.get()); '' ' – duy

+0

はい、問題ありません。 getコールは将来の値を常に返します(タイムアウトバージョンを使用すると例外をスローします) –

+0

ありがとうございました。 – duy

関連する問題