酉卒之子

导航

多线程数据缓存集合达到一定数量或达到指定时间间隔后,进行消费清空缓存集合

需求大概如下:

  从某平台(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();
    }

 

posted on 2021-01-11 11:43  酉卒之子  阅读(489)  评论(0编辑  收藏  举报