多線程 - ThreadPoolExecutor 常用的拒絕策略(RejectedExecutionHandler) 原

AbortPolicy

該策略是線程池的默認策略。使用該策略時,如果線程池隊列滿了丟掉這個任務並且拋出RejectedExecutionException異常。 源碼如下:

 public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    //不做任何處理,直接拋出異常
    throw new RejectedExecutionException("xxx");
}

DiscardPolicy

這個策略和AbortPolicy的slient版本,如果線程池隊列滿了,會直接丟掉這個任務並且不會有任何異常。 源碼如下:

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    //就是一個空的方法
}

DiscardOldestPolicy

這個策略從字面上也很好理解,丟棄最老的。也就是說如果隊列滿了,會將最早進入隊列的任務刪掉騰出空間,再嘗試加入隊列。 因爲隊列是隊尾進,隊頭出,所以隊頭元素是最老的,因此每次都是移除對頭元素後再嘗試入隊。 源碼如下:

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    if (!e.isShutdown()) {
        //移除隊頭元素
        e.getQueue().poll();
        //再嘗試入隊
        e.execute(r);
    }
}

CallerRunsPolicy

使用此策略,如果添加到線程池失敗,那麼主線程會自己去執行該任務,不會等待線程池中的線程去執行。就像是個急脾氣的人,我等不到別人來做這件事就乾脆自己幹。 源碼如下:

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    if (!e.isShutdown()) {
        //直接執行run方法
        r.run();
    }
}

自定義

......


原文:https://blog.csdn.net/jgteng/article/details/54411423

實例

    BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue(100);
    SendMsgRejectedExecutionHandler sendMsgRejectedExecutionHandler = new SendMsgRejectedExecutionHandler();
    ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(20, 20, 1, TimeUnit.SECONDS, workQueue, sendMsgRejectedExecutionHandler);

    private class SendMsgRunable implements Runnable {

        private String phone;
        private String msg;
        private Long unionId;

        public SendMsgRunable(String phone, String msg) {
            this.phone = phone;
            this.msg = msg;
        }

        @Override
        public void run() {
            xxx(phone, msg);
        }
    }

    private class SendMsgRejectedExecutionHandler implements RejectedExecutionHandler {
        @Override
        public void rejectedExecution(Runnable runnable, ThreadPoolExecutor executor) {
            //線程池已滿 直接丟棄
            //runnable.run();
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章