Java實現限定時間CountDownLatch并行場景
業(yè)務場景:
一個用戶數據接口,要求在20ms內返回數據,它的調用邏輯復雜,關聯接口多,需要從3個接口匯總數據,這些匯總接口最小耗時也需要16ms,全部匯總接口最優(yōu)狀態(tài)耗時需要16ms*3=48ms
解決方案:
使用并行調用接口,通過多線程同時獲取結果集,最后進行結果整合。在這種場景下,使用concurrent包的CountDownLatch完成相關操作。CountDownLatch本質上是一個計數器,把它初始化為與執(zhí)行任務相同的數量,當一個任務執(zhí)行完時,就將計數器的值減1,直到計算器達到0時,表示完成了所有任務,在await上等待線程就繼續(xù)執(zhí)行。
為上述業(yè)務場景封裝的工具類,傳入兩個參數:一個參數是計算的task數量,另外一個參數是整個大任務超時的毫秒數。
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ParallelCollector { private Long timeout; private CountDownLatch countDownLatch; ThreadPoolExecutor executor = new ThreadPoolExecutor(100, 200, 1, TimeUnit.HOURS, new ArrayBlockingQueue<>(100)); public ParallelCollector(int taskSize, Long timeOutMill) { countDownLatch = new CountDownLatch(taskSize); timeout = timeOutMill; } public void submitTask(Runnable runnable) { executor.execute(() -> { runnable.run(); countDownLatch.countDown(); }); } public void await() { try { this.countDownLatch.await(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { e.printStackTrace(); } } public void destroy() { this.executor.shutdown(); } }
當任務運行時間超過了任務的時間上限,就被直接停止,這就是await()的功能。
interface是一個模擬遠程服務的超時的測試類,程序運行后,會輸出執(zhí)行結果到map集合。
public class InterfaceMock { private volatile int num=1; public String slowMethod1() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return String.valueOf(num+1); }; public String slowMethod2() { return String.valueOf(num+1); }; public String slowMethod3() { return String.valueOf(num+1); }; }
并行執(zhí)行獲取結果測試類
@SpringBootTest class ThreadPoolApplicationTests { @Test void testTask() { InterfaceMock interfaceMock = new InterfaceMock(); ParallelCollector collector = new ParallelCollector(3, 20L); ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>(); collector.submitTask(()->map.put("method1",interfaceMock.slowMethod1())); collector.submitTask(()->map.put("method2",interfaceMock.slowMethod2())); collector.submitTask(()->map.put("method3",interfaceMock.slowMethod3())); collector.await(); System.out.println(map.toString()); collector.destroy(); } }
當method1()執(zhí)行時間大于20ms,則該方法直接被終止,結果map集沒有method1()的結果,結果如下:
總結
使用這種方式,接口能在固定時間內返回,注意CountDownLatch定義數量是任務個數,使用concurrentHashMap避免了并行執(zhí)行時發(fā)生錯亂,造成錯誤的結果的問題。
到此這篇關于Java實現限定時間CountDownLatch并行場景的文章就介紹到這了,更多相關Java CountDownLatch并行場景內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
解決@ResponseBody作用在返回類型為String的方法時的坑
這篇文章主要介紹了解決@ResponseBody作用在返回類型為String的方法時的坑,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06SpringCloud之分布式配置中心Spring Cloud Config高可用配置實例代碼
這篇文章主要介紹了SpringCloud之分布式配置中心Spring Cloud Config高可用配置實例代碼,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-04-04MyBatis中foreach標簽的collection屬性的取值方式
這篇文章主要介紹了MyBatis中foreach標簽的collection屬性的取值方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08