JAVA實現節流閥

JAVA實現節流閥

在前端開發中,有種效果叫做節流閥

顧名思義,節流閥的作用是限制某些事件的執行頻率,基本代碼如下:

obj.event = function(){
  clearTimeout(obj.timer);
  obj.timer = setTimeout(() => {
    execute
  }, timeout);
}

JAVA實現

在JAVA中,我們也需要一些類似的效果

抽象

我們抽象出一個pool,這個pool可以接受你的任務,如果是同一個任務,會覆蓋之前還沒執行的任務

class Pool {
    void execute(String key,Runnable runnable,long delay){}
}

這裏的key就代表你的任務,delay就是任務的間隔時間

使用線程池

我們可以引入線程池來簡化編碼

private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(6);

線程池的作用是進行任務調度,ScheduledExecutorService允許我們提交一個延遲執行的任務

思路

當程序員提交一個任務,pool會判斷這個任務是否在pool中待執行,
如果是待執行,則取消pool中的任務,後用新提交的這個任務替代它

scheduledExecutorService提交任務會返回一個future,在執行之前,我們可以取消它

完整代碼如下

void execute(String key,Runnable runnable,long delay){
    ScheduledFuture<?> task = map.get(key);
    if (task != null){
        task.cancel(false);
    }
    ScheduledFuture<?> schedule = scheduledExecutorService.schedule(()->{
        runnable.run();
        map.remove(key);
    }, delay, TimeUnit.MILLISECONDS);
    map.put(key,schedule);
}

這裏使用了一個map來記住任務的執行情況

測試

  • 第一個測試
// 應該只會輸出一個2
List<Integer> list = new ArrayList<>();
CountDownLatch latch = new CountDownLatch(1);
Pool pool = new Pool();
for (int i = 0; i < 3; i++) {
    int finalI = i;
    pool.execute("task",()->{
        System.out.println(finalI);
        list.add(finalI);
        latch.countDown();
    },1000);
    Thread.sleep(800);
}
latch.await();
assertEquals(1,list.size());
assertEquals(2,list.get(0));

這裏依次執行三次任務,但是這個任務的延遲時間是1000,任務執行的間隔是800

間隔比延遲實現還要小,所以前面2個任務會被忽略,結果只會輸出2

  • 第二個測試
// 應該輸出 0 1 2
List<Integer> list = new ArrayList<>();
CountDownLatch latch = new CountDownLatch(3);
Pool pool = new Pool();
for (int i = 0; i < 3; i++) {
    int finalI = i;
    pool.execute("task",()->{
        System.out.println(finalI);
        list.add(finalI);
        latch.countDown();
    },1000);
    Thread.sleep(1100);
}
latch.await();
assertEquals(3,list.size());
assertEquals(3,list.size());

這個測試任務間隔比延遲還要大,所以三個任務會被依次執行

輸出 0 1 2

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章