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

Incorrect work with threads inside ThreadPoolExecutor.

    Details

      Description

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

      ADDITIONAL OS VERSION INFORMATION :
      Linux rkom 4.10.0-42-generic #46~16.04.1-Ubuntu SMP Mon Dec 4 15:57:59 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
      Linux Mint 18.2 Sonya

      A DESCRIPTION OF THE PROBLEM :
      ThreadPoolExecutor does not allocate new threads (uses old threads) for new tasks

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create ThreadPoolExecutor with max pool thread size 3.
      Create 7 runnable task, submit it using ThreadPoolExecutor and save Future's object in local variable.
      –°all the get method for all Future


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      All method calls for the object are executed, the program is complete
      ACTUAL -
      The program hangs when trying to call the get method for the fourth Future object.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Logs from Java VisualVM program
      "pool-1-thread-3" #11 prio=5 os_prio=0 tid=0x00007fc358189800 nid=0x38bb waiting on condition [0x00007fc33958c000]
         java.lang.Thread.State: WAITING (parking)
              at sun.misc.Unsafe.park(Native Method)
              - parking to wait for <0x00000000d70606a0> (a java.util.concurrent.SynchronousQueue$TransferStack)
              at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
              at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:458)
              at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
              at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:924)
              at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
              at java.lang.Thread.run(Thread.java:748)

         Locked ownable synchronizers:
              - None

      "pool-1-thread-2" #10 prio=5 os_prio=0 tid=0x00007fc358188000 nid=0x38ba waiting on condition [0x00007fc33968d000]
         java.lang.Thread.State: WAITING (parking)
              at sun.misc.Unsafe.park(Native Method)
              - parking to wait for <0x00000000d70606a0> (a java.util.concurrent.SynchronousQueue$TransferStack)
              at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
              at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:458)
              at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
              at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:924)
              at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
              at java.lang.Thread.run(Thread.java:748)

         Locked ownable synchronizers:
              - None

      "pool-1-thread-1" #9 prio=5 os_prio=0 tid=0x00007fc358186000 nid=0x38b9 waiting on condition [0x00007fc33978e000]
         java.lang.Thread.State: WAITING (parking)
              at sun.misc.Unsafe.park(Native Method)
              - parking to wait for <0x00000000d70606a0> (a java.util.concurrent.SynchronousQueue$TransferStack)
              at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
              at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:458)
              at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
              at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:924)
              at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
              at java.lang.Thread.run(Thread.java:748)

         Locked ownable synchronizers:
              - None



      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.util.ArrayList;
      import java.util.List;
      import java.util.concurrent.Future;
      import java.util.concurrent.SynchronousQueue;
      import java.util.concurrent.ThreadPoolExecutor;
      import java.util.concurrent.TimeUnit;

      public class Test {
          public static void main(String[] args) throws Exception {
              System.out.println("main future - " + Thread.currentThread().getName());
              ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 3, 10L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
                      (r, executor1) -> System.out.println("Started in handler" + Thread.currentThread().getName() + " future " + r));
              List<Future> futures = new ArrayList<>();
              int maxThreads = 7;
              for (int i = 0; i < maxThreads; i++) {
                  final int k = i;
                  Future future = executor.submit(() -> {
                      System.out.println("assasasasa");
                  });
                  futures.add(future);
                  System.out.println("future - " + future);
              }
              try {
                  for (int i = 0; i < maxThreads; i++) {
                      System.out.println("before get future - " + futures.get(i));
                      futures.get(i).get();
                      System.out.println("before get future - " + futures.get(i));
                  }
              } catch (Exception e) {
                  throw new Exception(e);
              } finally {
                  for (Future future : futures) {
                      future.cancel(true);
                  }
              }
          }
      }
      ---------- END SOURCE ----------

        Attachments

          Activity

            People

            • Assignee:
              martin Martin Buchholz
              Reporter:
              webbuggrp Webbug Group
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: