Multithreading - a common rejection policy of ThreadPoolExecutor (RejectedExecutionHandler)

Keywords: Programming

AbortPolicy

This is the default policy for thread pools. When using this policy, if the thread pool queue is full, throw the task and throw a RejectedExecutionException exception. The source code is as follows:

 public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    //Throw an exception directly without any processing
    throw new RejectedExecutionException("xxx");
}

DiscardPolicy

If the thread pool queue is full, the task will be directly lost and there will be no exception. The source code is as follows:

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    //It's an empty way
}

DiscardOldestPolicy

This strategy is also well understood literally, discarding the oldest. That is to say, if the queue is full, the task that enters the queue earliest will be deleted to make room, and then try to join the queue. Because the queue is tail in and head out, the team head element is the oldest, so every time you remove the opposite element, you try to join the team. The source code is as follows:

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    if (!e.isShutdown()) {
        //Remove team head element
        e.getQueue().poll();
        //Try to join the team again
        e.execute(r);
    }
}

CallerRunsPolicy

With this policy, if adding to the thread pool fails, the main thread will execute the task itself and will not wait for the thread in the thread pool to execute. Like a quick tempered person, I can't wait for someone else to do it, just do it myself. The source code is as follows:

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    if (!e.isShutdown()) {
        //Execute run method directly
        r.run();
    }
}

custom

......

Original text: https://blog.csdn.net/jgteng/article/details/54411423

Example

    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) {
            //Thread pool full direct discard
            //runnable.run();
        }
    }

Posted by aQ on Wed, 04 Dec 2019 16:41:44 -0800