手动同步与自动同步防止并发
“同步设备”(无论是手工同步,还是自动同步)操作,是一个单一排它性操作,也就是无论点击多少次,还是当前同步时长太长,同一时间内只能有一个同步操作。
因此,我们需要添加代码来防止并发的同步操作,包括:
1)点击手工同步时,如果当前已经有同步任务,则需要提示:“系统正在同步中,请完成后再操作”
2)自动同步时,如果当前有同步任务(是手工,还是上一次未完成),则放弃本次同步操作,让原来的同步任务继续进行
防止并发的同步操作应该怎么做?
public class SyncDeviceWorkerManager { /** * 如果任务正在运行当中,则必须要等到任务完成,才会调度下一轮 */ private static volatile boolean commandRunning = false; /** * 建一个对象做锁 */ private final static Object LOCK = new Object(); /** * 初始化 */ public int doSyn() { synchronized (LOCK) { // 同步 if (commandRunning) { // 正在运行 System.out.println("正在处理"); return 0; // 直接返回标识,或者抛出异常 } else { commandRunning = true; } } // 新开线程异步处理逻辑 new Thread(new Runnable() { @Override public void run() { try { processData(); } finally { System.out.println("处理完成"); commandRunning = false; // 处理完成 } } }).start(); // .start();开始启动线程 return 1; // 表示执行同步 } private void processData() { System.out.println("开始处理"); try { Thread.sleep(3000); // 测试: 停3秒 } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { SyncDeviceWorkerManager manager = new SyncDeviceWorkerManager(); // 手工调整,也是这么调,自动也这么调 manager.doSyn(); // 执行processData() manager.doSyn(); // 不会执行processData() try { Thread.sleep(5000); // 停5秒 } catch (InterruptedException e) { e.printStackTrace(); } manager.doSyn(); // 执行processData() } }
//用来防止多次重入 private volatile boolean running = false;public void run() { if(isRunning()){ return ; }else{ setRunning(true); } try{ }catch(Exception e){ }finally{ setRunning(false); } } public synchronized boolean isRunning(){ return running; } private synchronized void setRunning(boolean r){ this.running = r; }