概述
目前在开发一个文档监控类工具时遇到一个问题,希望在文档编写过程中不对文档做备份,而在文档编写结束时再备份,这就需要一个防抖函数。
防抖函数,就是指触发事件后在n 秒内函数只能执行一次,如果在n 秒内又触发了事件,则会重新计算函数执行时间。 简单的说,当一个动作连续触发,则只执行最后一次。
实现
我们可以使用ScheduledExecutorService的schedule方法实现, 为每个任务分配一个唯一的 key,使用ConcurrentHashMap来存储 key-future,使用future的 cancel 方法来取消线程任务
packageorg.example.simple;importjava.util.concurrent.*;/***@authorCatch*@since2021-10-29*/publicclassDebounce{privatestaticfinalScheduledExecutorServiceSCHEDULE=Executors.newSingleThreadScheduledExecutor();//使用ConcurrentHashMap来存储FutureprivatestaticfinalConcurrentHashMap<Object,Future<?>>DELAYED_MAP=newConcurrentHashMap<>();/***抖动函数*/publicstaticvoiddebounce(finalObjectkey,finalRunnablerunnable,longdelay,TimeUnitunit){finalFuture<?>prev=DELAYED_MAP.put(key,SCHEDULE.schedule(()->{try{runnable.run();}finally{//如果任务运行完,则从map中移除DELAYED_MAP.remove(key);}},delay,unit));//如果任务还没运行,则取消任务if(prev!=null){prev.cancel(true);}}/***停止运行*/publicstaticvoidshutdown(){SCHEDULE.shutdownNow();}publicstaticvoidmain(String[]args){//1,2为每个任务的唯一keyDebounce.debounce("1",()->{System.out.println(11);},3,TimeUnit.SECONDS);Debounce.debounce("1",()->{System.out.println(22);},3,TimeUnit.SECONDS);Debounce.debounce("1",()->{System.out.println(33);},3,TimeUnit.SECONDS);Debounce.debounce("2",()->{System.out.println(44);},3,TimeUnit.SECONDS);Debounce.debounce("2",()->{System.out.println(44);},3,TimeUnit.SECONDS);Debounce.debounce("2",()->{System.out.println(44);},3,TimeUnit.SECONDS);}}