@Override
    public void execute(Runnable command) {
        if (command == null) {
            throw new NullPointerException();
        }

        try {
            super.execute(command);
        } catch (RejectedExecutionException rx) {
            // retry to offer the task into queue.
            final TaskQueue queue = (TaskQueue) super.getQueue();
            try {
                if (!queue.retryOffer(command, 0, TimeUnit.MILLISECONDS)) {
                    throw new RejectedExecutionException("Queue capacity is full.", rx);
                }
            } catch (InterruptedException x) {
                throw new RejectedExecutionException(x);
            }
        }
    }
@Test
    void testEagerThreadPool_rejectExecution2() {
        String name = "eager-tf";
        int cores = 1;
        int threads = 3;
        int queues = 2;
        long alive = 1000;

        // init queue and executor
        AtomicReference<Runnable> runnableWhenRetryOffer = new AtomicReference<>();
        TaskQueue<Runnable> taskQueue = new TaskQueue<Runnable>(queues) {
            @Override
            public boolean retryOffer(Runnable o, long timeout, TimeUnit unit) throws InterruptedException {
                if (runnableWhenRetryOffer.get() != null) {
                    runnableWhenRetryOffer.get().run();
                }
                return super.retryOffer(o, timeout, unit);
            }
        };
        final EagerThreadPoolExecutor executor = new EagerThreadPoolExecutor(
                cores,
                threads,
                alive,
                TimeUnit.MILLISECONDS,
                taskQueue,
                new NamedThreadFactory(name, true),
                new AbortPolicyWithReport(name, URL));
        taskQueue.setExecutor(executor);

        Semaphore semaphore = new Semaphore(0);
        Runnable runnable = () -> {
            try {
                semaphore.acquire();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        };
        for (int i = 0; i < 5; i++) {
            executor.execute(runnable);
        }

        await().until(() -> executor.getPoolSize() == threads);
        await().until(() -> executor.getQueue().size() == queues);

        Assertions.assertThrows(RejectedExecutionException.class, () -> executor.execute(runnable));

        runnableWhenRetryOffer.set(() -> {
            semaphore.release();
            await().until(() -> executor.getCompletedTaskCount() == 1);
        });
        executor.execute(runnable);
        semaphore.release(5);
        await().until(() -> executor.getActiveCount() == 0);
    }