一度CountDownLatchをSpringBootで@Asyncに合わせて使用することを記す


需要
プロジェクトはspringbootを使用し、サードパーティインタフェースを呼び出すたびにローカルデータのフィールドをクエリー条件として使用するシーンがあります.ベンダーが提供するインタフェースは、単一のクエリーのみであるため、ローカルからクエリーされたデータを巡回してインタフェースを呼び出すしかありません.これにより、応答時間が遅く、効率が低下します.
では、最適化方法を考えてみましょう.まず、マルチスレッドを有効にして、ローカル・データベースからクエリーされたレコードごとにサードパーティ・インタフェースを並列に呼び出すことができます.
まず、サードパーティインタフェースを呼び出し、データを埋め込むスレッドタスククラスを新規作成し、springの@Async注釈で非同期呼び出しを実現します.擬似コードは次のとおりです.
@Component
public class AsyncTask {


    /**
     *            
     */
    @Async
    public void queryTask(Entity entity){
       Data data = doPost();
       entity.setData(data);
    }
   
}

サービス層ループコール
public class Service {
    
    @Autowired
    private AsyncTask asyncTask;
    @Autowired
    private EntityMapper mapper;
    
    public List queryData(){
        
        List list = mapper.selectAll();
        for(Entity entity:list){
            asyncTask.queryTask(entity);
        }
        
       return list;
    }
}

これにより非同期リクエストインタフェースが実現され,効率が大幅に向上した.しかし、非同期呼び出しのため、データがまだ埋め込まれていないと返されます.これは明らかに私たちが望んでいる効果ではありません.AsyncTaskのすべてのスレッドが終了するのを待ってから、現在のスレッドタスクを呼び出す方法を返さなければなりません.そこでJDK 1を思い出した.5バージョン以降に提供されるカウンタCountDownLatch(CountDownLatchの使い方については本稿では述べないが、初めて使用して記録しただけで、間違ったところがあればアドバイスしてほしい).
考え方:
サービス層のメソッドでCountDownLatchをインスタンス化し、スレッド数を設定します.スレッド数は、ローカル・データベースからクエリされたlistの長さであり、スレッド・タスクに転送され、各スレッドが実行されるとcountDown()メソッドが呼び出されます.最後に、サービスレイヤでawait()メソッドを呼び出します.これにより、スレッドカウントがゼロになるまで、サービスのスレッドは待機します.
Service:
public class Service {
    
    @Autowired
    private AsyncTask asyncTask;
    @Autowired
    private EntityMapper mapper;
    
    public List queryData(){
        
        List list = mapper.selectAll();
        CountDownLatch latch = new CountDownLatch(list.size());
        for(Entity entity:list){
            asyncTask.queryTask(entity,latch);
        }
       latch.await();
       return list;
    }
}

AsyncTask:
@Component
public class AsyncTask {


    /**
     *            
     */
    @Async
    public void queryTask(Entity entity,CountDownLatch latch){
       Data data = doPost();
       entity.setData(data);
       latch.countDown();
    }
   
}

これで問題が解決する.