码迷,mamicode.com
首页 > 其他好文 > 详细

防止并发问题

时间:2018-07-05 15:55:59      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:color   cancel   connect   override   开始   添加   get   public   LEDE   


“同步设备”(无论是手工同步,还是自动同步)操作,是一个单一排它性操作,也就是无论点击多少次,还是当前同步时长太长,同一时间内只能有一个同步操作。

因此,我们需要添加代码来防止并发的同步操作,包括:

1)点击手工同步时,如果当前已经有同步任务,则需要提示:“系统正在同步中,请完成后再操作”

2)自动同步时,如果当前有同步任务(是手工,还是上一次未完成),则放弃本次同步操作,让原来的同步任务继续进行


防止并发的同步操作应该怎么做?



public
class SyncDeviceWorkerManager { private static ScheduledFuture<?> workerFuture; /** * 如果任务正在运行当中,则必须要等到任务完成,才会调度下一轮 */ private static volatile boolean commandRunning = false; private static SyncDeviceWorker command = null; /** * 一个任务的任务池 */ private static ScheduledExecutorService syncService = Executors.newScheduledThreadPool(2); /** * 初始化 * * @param sync 是否立即启动同步工作。 sync=true 表示启动任务, false表示不启动任务 */ public static void initSyncWorkerManager(boolean sync){ ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); //任务取消后,将被从队列中移除 executor.setRemoveOnCancelPolicy(true); //固定设置后,不希望被修改 syncService = Executors.unconfigurableScheduledExecutorService(executor); if(sync){ scheduledSyncDevice(null); } } /** * 同步设备调度 * * @param deviceRefreshConfig */ public static BooleanResult scheduledSyncDevice(DeviceRefreshConfig deviceRefreshConfig) { try{ DeviceRefreshConfig oldConfig = DeviceRefreshConfigManager.getDeviceRefreshConfig(); if(deviceRefreshConfig == null || !deviceRefreshConfig.equals(oldConfig)){ if(workerFuture != null){ workerFuture.cancel(false); } //重新创建任务 command = new SyncDeviceWorker(deviceRefreshConfig==null?oldConfig:deviceRefreshConfig); workerFuture = syncService.scheduleWithFixedDelay( command, 0L, command.getPeriod(), command.getTimeUnit()); } return BooleanResult.SUCCESS; }catch(Exception e){ LogManager.getInstance() .logSyncUError("[CCM同步]==> 重新调度同步任务失败,异常:", e); return BooleanResult.ofException(e); } }
手动同步
private
boolean syncDevice = false; @Post("/sync") public BooleanResult sync(){ LogManager.getInstance().info("[Post /devices/sync]==> 同步设备信息开始..."); if(!syncDevice){ syncDevice = true; try{ return SyncDeviceService.syncDeviceFromCCM(); }finally{ syncDevice = false; } } return BooleanResult.SUCCESS; }
    定时同步
SyncDeviceWorker.java



@Override
    public void run() {
        try{
            syncDevices();
        }finally{
            //在任务中需要手工释放数据库连接
            DataConnectionManager.returnConnection();
        }
        
    }

    /**
     * 同步设备
     */
    private void syncDevices() {
         LogManager.getInstance()
                      .logSyncUInfo("开始同步设备信息");
        SyncDeviceService.syncDeviceFromCCM()
                         .done(success->{
                             LogManager.getInstance()
                                        .logSyncUInfo("本次同步设备信息成功");
                         })
                         .fail(err->{
                             LogManager.getInstance()
                                        .error("[同步 CCM 设备]==> 设备同步失败,错误:", err);
                         });
    }

 

防止并发问题

标签:color   cancel   connect   override   开始   添加   get   public   LEDE   

原文地址:https://www.cnblogs.com/RealWorld/p/9268487.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!