--- old/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java 2021-01-09 11:35:38.133077715 -0800 +++ new/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java 2021-01-09 11:35:37.825080138 -0800 @@ -221,13 +221,18 @@ * simple feedback control mechanism that will slow down the rate that * new tasks are submitted. * - *
  • In {@link ThreadPoolExecutor.DiscardPolicy}, a task that - * cannot be executed is simply dropped. + *
  • In {@link ThreadPoolExecutor.DiscardPolicy}, a task that cannot + * be executed is simply dropped. This policy is designed only for + * those rare cases in which task completion is never relied upon. * *
  • In {@link ThreadPoolExecutor.DiscardOldestPolicy}, if the * executor is not shut down, the task at the head of the work queue * is dropped, and then execution is retried (which can fail again, - * causing this to be repeated.) + * causing this to be repeated.) This policy is rarely acceptable. In + * nearly all cases, you should also cancel the task to cause an + * exception in any component waiting for its completion, and/or log + * the failure, as illustrated in {@link + * ThreadPoolExecutor.DiscardOldestPolicy} documentation. * * * @@ -272,7 +277,7 @@ * * * - *

    Extension example. Most extensions of this class + *

    Extension example. Most extensions of this class * override one or more of the protected hook methods. For example, * here is a subclass that adds a simple pause/resume feature: * @@ -1149,8 +1154,10 @@ /** * Creates a new {@code ThreadPoolExecutor} with the given initial - * parameters, the default thread factory and the default rejected - * execution handler. + * parameters, the + * {@linkplain Executors#defaultThreadFactory default thread factory} + * and the {@linkplain ThreadPoolExecutor.AbortPolicy + * default rejected execution handler}. * *

    It may be more convenient to use one of the {@link Executors} * factory methods instead of this general purpose constructor. @@ -1184,7 +1191,7 @@ /** * Creates a new {@code ThreadPoolExecutor} with the given initial - * parameters and {@linkplain ThreadPoolExecutor.AbortPolicy + * parameters and the {@linkplain ThreadPoolExecutor.AbortPolicy * default rejected execution handler}. * * @param corePoolSize the number of threads to keep in the pool, even @@ -1220,7 +1227,7 @@ /** * Creates a new {@code ThreadPoolExecutor} with the given initial - * parameters and + * parameters and the * {@linkplain Executors#defaultThreadFactory default thread factory}. * * @param corePoolSize the number of threads to keep in the pool, even @@ -2081,7 +2088,20 @@ /** * A handler for rejected tasks that discards the oldest unhandled * request and then retries {@code execute}, unless the executor - * is shut down, in which case the task is discarded. + * is shut down, in which case the task is discarded. This policy is + * rarely useful in cases where other threads may be waiting for + * tasks to terminate, or failures must be recorded. Instead consider + * using a handler of the form: + *

     {@code
    +     * new RejectedExecutionHandler() {
    +     *   public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    +     *     Runnable dropped = e.getQueue().poll();
    +     *     if (dropped instanceof Future) {
    +     *       ((Future)dropped).cancel(false);
    +     *       // also consider logging the failure
    +     *     }
    +     *     e.execute(r);  // retry
    +     * }}}
    */ public static class DiscardOldestPolicy implements RejectedExecutionHandler { /**