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

ScheduledExecutorService.scheduleWithFixedDelay fails with max delay

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P2
    • Resolution: Duplicate
    • Affects Version/s: 7, 8u11, 9
    • Fix Version/s: 9
    • Component/s: core-libs
    • Labels:

      Backports

        Description

        FULL PRODUCT VERSION :
        java -version
        java version "1.7.0_07"
        Java(TM) SE Runtime Environment (build 1.7.0_07-b10)
        Java HotSpot(TM) Client VM (build 23.3-b01, mixed mode, sharing)

        A DESCRIPTION OF THE PROBLEM :
        When ScheduledExecutorService.scheduleWithFixedDelay is called with a delay of Long.MAX_VALUE and a TimeUnit longer than NANOSECONDS it fails badly, putting the executor service into an unusable state.
        The problem is due to the internal storage of the delay as a negative number in the "period" field of the ScheduledFutureTask (positive numbers mean fixed-rate rather than fixed-delay). The period field is set to TimeUnit.toNanos(-delay), and if the delay is large enough and the TimeUnit is longer than NANOSECONDS then this will be equal to Long.MIN_VALUE. Later, when the period field is used in .ScheduledThreadPoolExecutor.ScheduledFutureTask.setNextRunTime() it is converted back to a positive number with the unary minus operator before being passed to the triggerTime method. However, -Long.MIN_VALUE is a negative number (since the magnitude of Long.MIN_VALUE is one greater than the magnitude of Long.MAX_VALUE)! This results in triggerTime returning a time in the distant past.




        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.util.Date;
        import java.util.concurrent.Executors;
        import java.util.concurrent.ScheduledExecutorService;
        import java.util.concurrent.TimeUnit;

        public class ScheduledTaskBug
        {
            static public void main(String[] args) throws InterruptedException
            {
                ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
                executor.scheduleWithFixedDelay(new Runnable()
                {

                    @Override
                    public void run()
                    {
                        System.out.println("running scheduled task with delay: " + new Date());
                    }
                }, 0, Long.MAX_VALUE, TimeUnit.MICROSECONDS);
                // This second task should run right after the first run of the previously task scheduled
                // with a delay.
                // However, due to a bug in scheduleWithFixedDelay, it never runs. If the TimeUnit above is
                // changed to TimeUnit.NANOSECONDS then the following task will run as expected.
                executor.submit(new Runnable()
                {

                    @Override
                    public void run()
                    {
                        System.out.println("running immediate task: " + new Date());
                    }
                });
                Thread.sleep(5000);
                executor.shutdownNow();

            }
        }

        ---------- END SOURCE ----------

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  martin Martin Buchholz
                  Reporter:
                  robm Robert Mckenna
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  3 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved:
                    Imported: