@Override
    public void rejectedExecution(final Runnable r, final ThreadPoolExecutor e) {
        LOG.error("Thread pool [{}] is exhausted! {}.", threadPoolName, e.toString());

        dumpJvmInfoIfNeeded();

        if (r instanceof RejectedRunnable) {
            ((RejectedRunnable) r).rejected(); // user-defined rejecting
        } else {
            if (!e.isShutdown()) {
                final BlockingQueue<Runnable> queue = e.getQueue();
                final int discardSize = queue.size() >> 1;
                for (int i = 0; i < discardSize; i++) {
                    queue.poll();
                }

                try {
                    queue.put(r);
                } catch (final InterruptedException ignored) {
                    // should not be interrupted
                }
            }
        }
    }
If the current task implements {@link RejectedRunnable},
then the users will be allowed to implement user-defined
rejecting, otherwise some of the existing tasks in the
queue will be discarded in FIFO mode.

@author jiachun.fjc
jraft-rheakv/rheakv-core/src/main/java/com/alipay/sofa/jraft/rhea/util/concurrent/RejectedTaskPolicyWithReport.java