多執行緒資料快取集合達到一定數量或達到指定時間間隔後,進行消費清空快取集合
阿新 • • 發佈:2021-01-11
需求大概如下:
從某平臺(webservice)接收車記錄資料,但是資料量是不確定的,有時候很多有時候又很少;
為了及時將接收到的資料轉發出去,且儘可能減少轉發的頻次。於是設計一個接收資料的快取集合,規定當集合的資料量達到一定資料量後,進行一次性消費;同時為了避免有時候接收的資料量很少,達不到轉發的閾值,而出現少部分資料殘留很久的情況,於是新增一個定時任務,定時將快取集合中的資料全部轉發出去。
下面看核心部分程式碼:
@Value("${each-file-size}") private int eachFileSize;//配置檔案可配置,轉發的閾值 privateExecutor queuePool = Executors.newFixedThreadPool(10); private AtomicReference<List<CarRecord>> atomicReference = new AtomicReference<>(new CopyOnWriteArrayList<>()); /** * 達到一定數量,或一定時間後,呼叫sendCarRecord進行批量操作 */ public void carRecord2Queue(CarRecord carRecord) { queuePool.execute(new Runnable() { @Override public void run() {
//下載圖片,耗時操作 downloadImgWithRetry(carRecord); if (StringUtils.isNotBlank(carRecord.getSceneImageData())) { atomicReference.get().add(carRecord); if (atomicReference.get().size() >= eachFileSize) { sendCarRecord(); } } } }); }public void sendCarRecord() { if (atomicReference.get().size()==0){ return; } val carRecords = atomicReference.getAndSet(new CopyOnWriteArrayList<>()); if (carRecords.size() == 0) { return; } //寫檔案,消費快取集合的資料 this.transmitByJoinType(carRecords); }
另外,還需要一個定時任務,調sendCarRecord()方法
@Async //@Scheduled(cron = "0/10 * * * * ?") @Scheduled(fixedDelay = 10 * 1000) //間隔10秒 public void check_car_record() { log.info("--------------定時檢查 check_car_record---------------"); processService.sendCarRecord(); }