There exists a race condition in org.glassfish.enterprise.concurrent.internal.ManagedScheduledThreadPoolExecutor
which is easily triggered by scheduling a task with ManagedScheduledExecutorService#scheduleAtFixedRate
that occasionally takes longer than the interval at which the task is scheduled.
Example with 2 threads (th1, th2) in the thread pool:
- th1: runWorker -> getTask() : gets the task to execute
- th1: runWorker -> beforeExecute() : runs the setup context handles and saves the reset handles to the task
- th1: runWorker -> runAndReset() : runs the task (which takes longer than the scheduled interval) and re-adds it to the queue with a
nextRunTime
in the past - th2: runWorker -> getTask() : gets the task to execute
- th2: runWorker -> beforeExecute() : runs the setup context handles and saves the reset handles to the task, overwriting the reset handles from th1
- th1: runWorker -> afterExecute() : executes the reset handles of the task, setting them to
null
on the task - th2: runWorker -> runAndReset() : runs the task and re-adds it to the queue
- th2: runWorker -> afterExecute() : reset handles are
null
, no reset is performed