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

The accuracy of the java.util.concurrent.locks.LockSupport.parkNanos has dropped after upgrading the Windows 10 to version 1703

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version "1.8.0_121"
      Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
      Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Windows 10 version 1703

      A DESCRIPTION OF THE PROBLEM :
      The accuracy of method java.util.concurrent.locks.LockSupport.parkNanos under Windows 10 before version 1703 was 1 millisecond (by median). After update Windows 10 to version 1703 the accuracy became 16 millisecond (by median).

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run test:

          @Test
          public void testParkNanos() throws Exception {
              final int size = 1000;
              final long[] parkData = new long[size];
              final long[] sleepData = new long[size];
              for (int i = 0; i < size; i++) {
                  long point = System.currentTimeMillis();
                  LockSupport.parkNanos(1L);
                  parkData[i] = System.currentTimeMillis() - point;

                  point = System.currentTimeMillis();
                  Thread.sleep(1L);
                  sleepData[i] = System.currentTimeMillis() - point;
              }

              Arrays.sort(parkData);
              Arrays.sort(sleepData);

              System.out.println();
              System.out.println("parkNanos:");
              System.out.println("Min: " + parkData[0]);
              System.out.println("Median: " + parkData[parkData.length / 2]);
              System.out.println("80%: " + parkData[Math.round(((float) parkData.length) * 0.80F)]);
              System.out.println("90%: " + parkData[Math.round(((float) parkData.length) * 0.90F)]);
              System.out.println("99%: " + parkData[Math.round(((float) parkData.length) * 0.99F)]);
              System.out.println("Max: " + parkData[parkData.length - 1]);
              System.out.println();

              System.out.println();
              System.out.println("sleep:");
              System.out.println("Min: " + sleepData[0]);
              System.out.println("Median: " + sleepData[sleepData.length / 2]);
              System.out.println("80%: " + sleepData[Math.round(((float) sleepData.length) * 0.80F)]);
              System.out.println("90%: " + sleepData[Math.round(((float) sleepData.length) * 0.90F)]);
              System.out.println("99%: " + sleepData[Math.round(((float) sleepData.length) * 0.99F)]);
              System.out.println("Max: " + sleepData[sleepData.length - 1]);
              System.out.println();
          }


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Under Windows 10 version 1607:

      parkNanos:
      Min: 1
      Median: 1
      80%: 1
      90%: 2
      99%: 7
      Max: 23


      sleep:
      Min: 1
      Median: 1
      80%: 1
      90%: 2
      99%: 5
      Max: 94

      ACTUAL -
      Under Windows 10 version 1703:

      parkNanos:
      Min: 1
      Median: 16
      80%: 16
      90%: 27
      99%: 30
      Max: 48


      sleep:
      Min: 1
      Median: 1
      80%: 2
      90%: 2
      99%: 6
      Max: 12


      REPRODUCIBILITY :
      This bug can be reproduced often.

      ---------- BEGIN SOURCE ----------
          @Test
          public void testParkNanos() throws Exception {
              final int size = 1000;
              final long[] parkData = new long[size];
              final long[] sleepData = new long[size];
              for (int i = 0; i < size; i++) {
                  long point = System.currentTimeMillis();
                  LockSupport.parkNanos(1L);
                  parkData[i] = System.currentTimeMillis() - point;

                  point = System.currentTimeMillis();
                  Thread.sleep(1L);
                  sleepData[i] = System.currentTimeMillis() - point;
              }

              Arrays.sort(parkData);
              Arrays.sort(sleepData);

              System.out.println();
              System.out.println("parkNanos:");
              System.out.println("Min: " + parkData[0]);
              System.out.println("Median: " + parkData[parkData.length / 2]);
              System.out.println("80%: " + parkData[Math.round(((float) parkData.length) * 0.80F)]);
              System.out.println("90%: " + parkData[Math.round(((float) parkData.length) * 0.90F)]);
              System.out.println("99%: " + parkData[Math.round(((float) parkData.length) * 0.99F)]);
              System.out.println("Max: " + parkData[parkData.length - 1]);
              System.out.println();

              System.out.println();
              System.out.println("sleep:");
              System.out.println("Min: " + sleepData[0]);
              System.out.println("Median: " + sleepData[sleepData.length / 2]);
              System.out.println("80%: " + sleepData[Math.round(((float) sleepData.length) * 0.80F)]);
              System.out.println("90%: " + sleepData[Math.round(((float) sleepData.length) * 0.90F)]);
              System.out.println("99%: " + sleepData[Math.round(((float) sleepData.length) * 0.99F)]);
              System.out.println("Max: " + sleepData[sleepData.length - 1]);
              System.out.println();
          }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Use Thread.sleep instead of LockSupport.parkNanos to obtain accuracy 1 millisecond

            dholmes David Holmes
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: