多线程数据缓存集合达到一定数量或达到指定时间间隔后,进行消费清空缓存集合
需求大概如下:
从某平台(webservice)接收车记录数据,但是数据量是不确定的,有时候很多有时候又很少;
为了及时将接收到的数据转发出去,且尽可能减少转发的频次。于是设计一个接收数据的缓存集合,规定当集合的数据量达到一定数据量后,进行一次性消费;同时为了避免有时候接收的数据量很少,达不到转发的阈值,而出现少部分数据残留很久的情况,于是添加一个定时任务,定时将缓存集合中的数据全部转发出去。
下面看核心部分代码:
@Value("${each-file-size}")
private int eachFileSize;//配置文件可配置,转发的阈值
private Executor 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(); }
浙公网安备 33010602011771号