溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JAVA實(shí)現(xiàn)節(jié)流閥

發(fā)布時(shí)間:2020-08-08 07:56:18 來(lái)源:ITPUB博客 閱讀:134 作者:guge60 欄目:編程語(yǔ)言

JAVA實(shí)現(xiàn)節(jié)流閥

在前端開(kāi)發(fā)中,有種效果叫做節(jié)流閥

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

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

JAVA實(shí)現(xiàn)

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

抽象

我們抽象出一個(gè)pool,這個(gè)pool可以接受你的任務(wù),如果是同一個(gè)任務(wù),會(huì)覆蓋之前還沒(méi)執(zhí)行的任務(wù)

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

這里的key就代表你的任務(wù),delay就是任務(wù)的間隔時(shí)間

使用線程池

我們可以引入線程池來(lái)簡(jiǎn)化編碼

private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(6);

線程池的作用是進(jìn)行任務(wù)調(diào)度,ScheduledExecutorService允許我們提交一個(gè)延遲執(zhí)行的任務(wù)

思路

當(dāng)程序員提交一個(gè)任務(wù),pool會(huì)判斷這個(gè)任務(wù)是否在pool中待執(zhí)行,
如果是待執(zhí)行,則取消pool中的任務(wù),后用新提交的這個(gè)任務(wù)替代它

scheduledExecutorService提交任務(wù)會(huì)返回一個(gè)future,在執(zhí)行之前,我們可以取消它

完整代碼如下

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);}

這里使用了一個(gè)map來(lái)記住任務(wù)的執(zhí)行情況

測(cè)試

  • 第一個(gè)測(cè)試
// 應(yīng)該只會(huì)輸出一個(gè)2List<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));

這里依次執(zhí)行三次任務(wù),但是這個(gè)任務(wù)的延遲時(shí)間是1000,任務(wù)執(zhí)行的間隔是800

間隔比延遲實(shí)現(xiàn)還要小,所以前面2個(gè)任務(wù)會(huì)被忽略,結(jié)果只會(huì)輸出2

  • 第二個(gè)測(cè)試
// 應(yīng)該輸出 0 1 2List<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());

這個(gè)測(cè)試任務(wù)間隔比延遲還要大,所以三個(gè)任務(wù)會(huì)被依次執(zhí)行

輸出 0 1 2


作者:0xcaffebabe
鏈接:https://www.imooc.com/article/305039
轉(zhuǎn)自來(lái)源:慕課網(wǎng)

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI