項目背景:前端發送一次請求,後臺通過遠程連接技術grpc獲取數據。在一次請求中分多次請求grpc服務端,且請求爲單線程,需要等待上一次請求結束後再發送請求,嚴重影響性能。
解決方案:採用多線程併發發送多個請求。
解決步驟:
1:創建線程連接池:
private ExecutorService threadPool = Executors.newFixedThreadPool(10);
2:獲取需要發送請求的次數
使用 CountDownLatch ,判斷所有線程是否執行完畢
final CountDownLatch latch = new CountDownLatch(num);
CountDownLatch 有兩個方法,countDown(),數值 減1
await(),當CountDownLatch的值爲0時,程序繼續執行,否則程序阻塞
3:使用線程
由於需要得到遠程連接的返回值,這邊使用Callable接口獲取返回值。
try { Future res = threadPool.submit(new Callable<StatisticsCount.StatisticsCountResVo>() { @Override public StatisticsCount.StatisticsCountResVo call() throws Exception { return stub.getCountInfo(rpcVo); } }); try { return res; } catch (Exception e) { e.printStackTrace(); logger.error(e.getMessage()); logger.error("獲取rpc結果失敗"); } } finally { latch.countDown(); logger.info("lanthc:" + latch.getCount() + "--fp:" + fp); }
new Callable<StatisticsCount.StatisticsCountResVo>() 可以自定義返回值類型,同時CountDownLatch的值減一,同時喚醒阻塞的線程。
3:獲取線程的返回值
Future<StatisticsCount.StatisticsCountResVo> res= sendBaseSpecs(threadPool, rpcVo, latch, stub, statisticsCountVo.getFp(), base); latch.await(); base = res.get();
其中,latch.await() 一直阻塞直到latch的值爲0且所有線程執行完畢(有返回值)