ScheduledThreadPoolExecutor之remove方法

之前用定時任務的線程池,設置了個任務,但是突然今天產品說,某些個操作需要中斷某些任務(如果任務還沒有執行),使其不能再到點執行了。於是查了API果然有這樣一個方法。

 

一看API,需要移除的是一個Runnable對象,想當然的就把任務調度的傳入的Runable對象保留下來,然後進行刪除。簡要代碼如下

Runnable:
    static class Task implements Runnable {

        @Override
        public void run() {
            System.out.println(Instant.now().getEpochSecond());
        }
    }
    public static void main(String[] args) {
        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(10);
        Task task = new Task();
        scheduledThreadPoolExecutor.schedule(new Task(), 10, TimeUnit.SECONDS);
        scheduledThreadPoolExecutor.remove(task);
        System.out.println(Instant.now().getEpochSecond());
    }

 

一執行,完蛋10s過後任務還是執行了,任務並沒有移除

 

 

看了下ScheduledThreadPoolExecutor中重寫的remove方法是去他自己的BlockingQueue裏面刪除了一個任務,也就是這個方法ScheduledThreadPoolExecutor.DelayedWorkQueue#remove,這個的入參變成了Object,而且一看這個queue隊列裏面裝的是RunnableScheduledFuture這個對象,這傢伙肯定是實現了Runnable接口的,一看果然是,那麼這個東西放到隊列去的呢?

 

 

 

再看schedule方法是返回了一個值的,猜想了下是不是封裝過我們傳入的Runbale對象,於是決定remove方法的返回值,結果一看返回的ScheduledFuture對象沒有實現Runnable接口,而remove要的Runnable。有一點點坑的地方來了,RunnableScheduledFuture這個是

ScheduledFuture這個的子類,面向接口編程嘛,最後是返回了一個父類接口,但是父類接口沒有實現Runnable,子類才實現了。

 

 

最後再看ScheduledThreadPoolExecutor#delayedExecute這個方法裏面剛好把剛纔的那個RunnableScheduledFuture對象傳入進去了並且加入到隊列中去了。這樣就和前面聯繫起來了

 

 

 

如此一來 我們只需要把schedule方法的返回值強轉成子類對象RunnableScheduledFuture,保存下來,然後再去調用remove應該可以成功的移除了

    public static void main(String[] args) {
        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(10);
        Task task = new Task();
        RunnableScheduledFuture<?> schedule =
                (RunnableScheduledFuture<?>) scheduledThreadPoolExecutor.schedule(task, 10, TimeUnit.SECONDS);
        scheduledThreadPoolExecutor.remove(schedule);
        System.out.println(Instant.now().getEpochSecond());


    }

 

雖然有API供參考,但是就像前面只看API的時候,那個Runnable參數到底該什麼,還得要去看下ScheduledThreadPoolExecutor中別人是怎麼實現的才能知道。

 

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