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

ThreadPoolExecutor fails to halt extra threads if reconfigured to a smaller pool

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 6
    • core-libs

      FULL PRODUCT VERSION :
      java version "1.6.0_22"
      Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
      Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Linux deluge 2.6.35-27-generic #48-Ubuntu SMP Tue Feb 22 20:25:46 UTC 2011 x86_64 GNU/Linux


      A DESCRIPTION OF THE PROBLEM :
      If a ThreadPoolExecutor is reconfigured via setMaximumPoolSize() to a lower number of threads, existing threads beyond the new limit are not terminated.

      The intent seems to be to terminate them, but the implementation doesn't actually work.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run the attached source code.
      Note that after reconfiguration, there are still 10 threads in the pool, but the new executor configuration specifies a maximum of 5 threads.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Using the latest (2011/03/17) jsr166.jar from http://g.oswego.edu/dl/concurrency-interest/, I get the expected results:

      oliver@deluge:~$ java -Xbootclasspath/p:jsr166.jar TestTPEShrink
      Initially, pool size = 0
      After execution, pool size = 10
      After reconfiguration, pool size = 5
      After reconfiguration and execution, pool size = 5



      ACTUAL -
      Using Java 1.6.0_22, I get these incorrect results:

      oliver@deluge:~$ java TestTPEShrink
      Initially, pool size = 0
      After execution, pool size = 10
      After reconfiguration, pool size = 10
      After reconfiguration and execution, pool size = 10


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.util.*;
      import java.util.concurrent.*;

      public class TestTPEShrink {
          private static void runSomeTasks(ExecutorService executor) throws Exception {
              List<Future<?>> completionList = new ArrayList<Future<?>>();
              for (int i = 0; i < 100; ++i) {
                  completionList.add(executor.submit(new Runnable() {
                          public void run() {
                              /* nothing */
                          }
                      }));
              }
              
              for (Future<?> completion : completionList)
                  completion.get();
          }

          public static void main(String[] args) throws Exception {
              // create a 10-thread executor

              ThreadPoolExecutor executor =
                  new ThreadPoolExecutor(10, // core pool size
                                         10, // max pool size
                                         Long.MAX_VALUE, // keepalive
                                         TimeUnit.MILLISECONDS, // keepalive unit
                                         new LinkedBlockingQueue<Runnable>());

              System.err.println("Initially, pool size = " + executor.getPoolSize());

              // run tasks to trigger thread creation
              runSomeTasks(executor);
              System.err.println("After execution, pool size = " + executor.getPoolSize());
              
              // reconfigure the executor to 5 threads
              executor.setCorePoolSize(5);
              executor.setMaximumPoolSize(5);
                                         
              // give it some time to think about it.
              Thread.sleep(5000);

              System.err.println("After reconfiguration, pool size = " + executor.getPoolSize());

              // maybe we need to run some jobs..
              runSomeTasks(executor);
              Thread.sleep(5000);
              System.err.println("After reconfiguration and execution, pool size = " + executor.getPoolSize());

              System.exit(0);
          }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      Use an updated JSR166 jar.
      I have not attempted to isolate the bug further.

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: