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

Executors.newSingleThreadExecutor().submit(runnable) throws RejectedExecutionException

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version "1.8.0_51"
      Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
      Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      linux_suse_sles_11 and windows 7-64bit

      A DESCRIPTION OF THE PROBLEM :
      When spring framework init a bean object, it will invoke afterPropertiesSet() method.
      My code like this:
      public void afterPropertiesSet()
      {
      Executors.newSingleThreadExecutor().submit(new Runnable()
      {
      @Override
      public void run()
      {
      Thread.currentThread().setName("StartUp-1");
      try
      {
      .....
      }
      catch (Exception e)
      {
      logger.error("", e);
      }
      }

      });
      }
      but there throw a RejectedExeception:
      Caused by: java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@694abf75 rejected from java.util.concurrent.ThreadPoolExecutor@15e7578d[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
      at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
      at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
      at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
      at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
      at java.util.concurrent.Executors$DelegatedExecutorService.submit(Executors.java:678)
      at demo.MyService.afterPropertiesSet(TopoService.java:248)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
      ... 18 more

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      I submited this bug at JDK-8144799. But that issue has been closed. This time I find a way to reproducing that issue.

      There has possible the ThreadPoolExecutor already finalize by jvm before submit Runnable instance?
      I wrote a test case like this:

      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;

      public class A implements Runnable {
          public void afterProperties() {
              Executors.newSingleThreadExecutor().submit(new Runnable() {
                  @Override
                  public void run() {
                      System.out.println(Thread.currentThread().getName());
                  }
              });
          }
          @Override
          public void run() {
              afterProperties();
          }
          public static void main(String[] args) throws Exception {
              ExecutorService execMain = Executors.newFixedThreadPool(2);
              A testcase = new A();
              for (int i = 0; i < 1000; i++) {
                  execMain.submit(testcase);
              }
          }
      }

      The byte code for A.afterProperties:
        public void afterProperties();
           0 invokestatic java.util.concurrent.Executors.newSingleThreadExecutor() : java.util.concurrent.ExecutorService [17]
           3 new A$1 [23]
           6 dup
           7 aload_0 [this]
           8 invokespecial A$1(A) [25]
          11 invokeinterface java.util.concurrent.ExecutorService.submit(java.lang.Runnable) : java.util.concurrent.Future [28] [nargs: 2]
          16 pop
          17 return
              
      Most of the time, I think there have 1001 instance for ThreadPoolWorker. But when I dump this process's memory, use MAT checked the number of the ThreadPoolWorker. The count just some hundreds, less than 1000, and the ctl.value of the some instance is 1610612736.
      I think maybe invoke submit() method, the instanceof of ThreadPoolExecutor already finalized by jvm. I check the ThreadPoolExecutor.finalize(), when it invoked, the shutdown() method will be invoked.
      Then sumbit the A$1, the ctl status arleady "SHUTDOWN", so the exception message like "rejected from java.util.concurrent.ThreadPoolExecutor@25298878[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]".




      REPRODUCIBILITY :
      This bug can be reproduced occasionally.

      ---------- BEGIN SOURCE ----------
      Then I change the test case like this, and reproduce the exception


      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;

      public class A implements Runnable {
          public void afterProperties() {
              Executors.newSingleThreadExecutor().submit(new Runnable() {
                  @Override
                  public void run() {
                      System.out.println(Thread.currentThread().getName());
                  }
              });
          }
          @Override
          public void run() {
              try {
                  afterProperties();
              } catch (Exception e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
                  System.exit(-1);
              }
          }
          public static void main(String[] args) throws Exception {
              ExecutorService execMain = Executors.newFixedThreadPool(2);
              A testcase = new A();
              execMain.submit(new Runnable(){

                  @Override
                  public void run() {
                      while(true) {
                          System.gc();
                          try {
                              Thread.sleep(2000);
                          } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                          }
                      }
                  }});
              for (;;) {
                  execMain.submit(testcase);
                  Thread.yield();
              }
          }
      }

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

            martin Martin Buchholz
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: