Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8255556

Resizing failure in ForkJoinPool.WorkQueue does not reject further pushes

XMLWordPrintable

      This is a bug spotted by my colleague Lee Raiford (lraiford@amazon.com)

      * After a ForkJoinPool rejects an external submission with a reason of "Queue capacity exceeded", incoming task submissions start overwriting existing queued tasks, instead of being rejected.

      Here's more details:

      The exception is thrown from ForkJoinPool.WorkQueue::growArray either because the array length exceeds the capacity or OOM during allocation: https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java#L912

      There are two behaviors we believe that are unreasonable:
      * The RejectedExecutionException is thrown from growArray *after* the task is already pushed to array in lockedPush (ForkJoinPool.java#L864). Even the exception message "Queue capacity exceeded" is clear, but the exception name RejectedExecutionException is misleading: It makes developer feel the push was unsuccessful (and therefore may try to recommit it to the pool) and,
      * When developer tries to recommit the task, the push is successful because the resizing condition (d == m, L866) is not met anymore (and the task overwrites previous task in the array).

      Here are the fixes we suggest:
      * (minimum) WorkQueue should reject further pushes after a resizing failure (Or, when previous sizing failed, try resizing again).
      * (Optional) WorkQueue should use a different exception for resizing failure (something like QueueCapacityExceededException).

      See the attached ExceedForkJoinPoolCapacity.java as a simple repro program.

            martin Martin Buchholz
            luoziyi Ziyi Luo (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: