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

ForkJoinPool:shutdown() interrupts thread when waiting for termination

XMLWordPrintable

      ADDITIONAL SYSTEM INFORMATION :
      Reproduced on ubuntu 20.04.6 and windows 11
      Is present in Java 19.0.1, 20.0.2 and 21.0.4 but not in 17.0.11, 18.0.2 and 22.0.1

      A DESCRIPTION OF THE PROBLEM :
      When calling ForkJoinPool:shutdown() and waiting for the termination of the forkjoinpool via ForkJoinPool:awaitTermination(...) a running thread is interrupted. If a runnable is directly submitted to the forkjoinpool without involving the CompletableFuture no interrupt occurs.
      The code example is a simplified version of the reproducer from JDK-8200520 to which this issue may be related to.

      REGRESSION : Last worked in version 18

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      See the code example

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Program terminates after a minute or the submitted runnable is finished.
      ACTUAL -
      Thread is interrupted before finishing/the wait time elapses.

      java.lang.InterruptedException
      at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:386)
      at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2073)
      at ForkJoinShutdown.lambda$main$1(ForkJoinShutdown.java:19)
      at java.base/java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1403)
      at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
      at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1311)
      at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1841)
      at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1806)
      at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)

      ---------- BEGIN SOURCE ----------
      import java.util.concurrent.CompletableFuture;
      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;
      import java.util.concurrent.TimeUnit;

      // based on the reproducer from JDK-8200520
      class ForkJoinShutdown {

          public static void main(String[] args) {
              ExecutorService pool = Executors.newWorkStealingPool();

              pool.submit(() -> {
                  try {
                      CompletableFuture.runAsync(() -> {
                          try {
                              Thread.sleep(1000);
                          } catch (InterruptedException e) {
                              System.err.println("Interrupted during sleep");
                          }
                      }).get();
                      System.out.println("Pass");
                  } catch (Exception e) {
                      System.err.println("Fail");
                      e.printStackTrace();
                  }
              });

              try {
                  pool.shutdown();
                  pool.awaitTermination(1, TimeUnit.MINUTES);
              } catch (InterruptedException e) {
                  System.err.println("Interrupted during shutdown");
              }
          }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      Removing the CompletableFuture from the submitted runnable i.e.:

      pool.submit(() -> {
      try {
      Thread.sleep(1000);
      System.out.println("Pass");
      } catch (Exception e) {
      System.err.println("Fail");
      e.printStackTrace();
      }
      });

      FREQUENCY : always


            vklang Viktor Klang
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: