title: Java - ExecutorService has a maximum size
body: <p>Is there any way to go through a huge database and apply some jobs in parallel for bench of entries? 
  I tried with ExecutorService, but we have to shutdown() in order to know the pool size...</p>
  
  <p>So my best solution is:</p>
  
  <pre><code>import java.util.concurrent.ExecutorService;
  import java.util.concurrent.Executors;
  import java.util.concurrent.ThreadPoolExecutor;
  import java.util.concurrent.TimeUnit;
  
  public class TestCode
  {
  private static List&lt;String&gt; getIds(int dbOffset, int nbOfArticlesPerRequest) 
  {
      return Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29");
  }
  
  public static void main(String args[]) throws Exception
  {
      int dbOffset = 0;
      int nbOfArticlesPerRequest = 100;
      int MYTHREADS = 10;
      int loopIndex = 0;
      boolean bContinue=true;
      Runnable worker;
  
  
  
      while(bContinue) // in this loop we'll constantly fill the pool list
      {
          loopIndex++;
          ExecutorService executor = Executors.newFixedThreadPool(MYTHREADS); // NOT IDEAL, BUT EXECUTORSERVICE CANNOT BE REUSED ONCE SHUTDOWN...
  
          List&lt;String&gt; ids = getIds(dbOffset, nbOfArticlesPerRequest ); // getIds(offset, rows_number)
          for(String id: ids) {
              worker = new MyRunnable(id);
              executor.execute(worker);
          }
  
          executor.shutdown();
          while (!executor.isTerminated()) {
              System.out.println("Pool size is now " + ((ThreadPoolExecutor) executor).getActiveCount()+
                      " - queue size: "+ ((ThreadPoolExecutor) executor).getQueue().size()
              );
              TimeUnit.MILLISECONDS.sleep(500);
          }
  
          if(loopIndex&gt;=3) {
              System.out.println("\nEnd the loop #"+loopIndex+" ===&gt; STOOOP!\n");
              bContinue = false;
          }
          dbOffset+=nbOfArticlesPerRequest;
      }
  }
  
  
  
  public static class MyRunnable implements Runnable {
  
      private final String id;
  
      MyRunnable(String id) {
          this.id = id;
      }
  
          @Override
          public void run()
          {
              System.out.println("Thread '"+id+"' started");
              try {
                  TimeUnit.MILLISECONDS.sleep(2000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              System.out.println("Thread '"+id+"' stopped");
          }
      }
  }
  </code></pre>
  
  <p>This is working fine, but the drawback is that at every end of loop I need to wait the last threads to finish.</p>
  
  <p>e.g.: when only 3 threads are running...</p>
  
  <p>I did the following in order to solve this problem, but is that "safe"/correct?</p>
  
  <p>BTW: is there any way to know how many tasks/threads are in the queue?</p>
  
  <pre><code>    int dbOffset = 0;
      int nbOfArticlesPerRequest = 5; //100;
      int MYTHREADS = 2;
      int loopIndex = 0;
  
      ExecutorService executor = Executors.newFixedThreadPool(MYTHREADS); // **HERE IT WOULD BE A GLOBAL VARIABLE**
         while(bContinue) // in this loop we'll constantly fill the pool list
          {
              loopIndex++;
  
              List&lt;String&gt; ids = getIds(dbOffset, nbOfArticlesPerRequest ); // getIds(offset, rows_number)
               for(String id: ids) {
                      worker = new MyRunnable(id);
                      executor.execute(worker);
               }
  
              while (!executor.isTerminated() &amp;&amp; ((ThreadPoolExecutor) executor).getActiveCount() &gt;= MYTHREADS) {
                  System.out.println("Pool size is now " + ((ThreadPoolExecutor) executor).getActiveCount()+
                          " - queue size: "+ ((ThreadPoolExecutor) executor).getQueue().size()
                  );
                  TimeUnit.MILLISECONDS.sleep(500);
              }
  
              if(loopIndex&gt;=3) {
                  System.out.println("\nEnd the loop #"+loopIndex+" ===&gt; STOOOP!\n");
                  bContinue = false;
              }
              dbOffset+=nbOfArticlesPerRequest;
          }
  
      executor.shutdown();
      // Wait until all threads are finish
      while (!executor.isTerminated()) {
          System.out.println("Pool size is now " + ((ThreadPoolExecutor) executor).getActiveCount()+
                  " - queue size: "+ ((ThreadPoolExecutor) executor).getQueue().size()
          );
          TimeUnit.MILLISECONDS.sleep(500);
      }
  </code></pre>
  
  <p><strong>EDIT:</strong></p>
  
  <p><strong>I try to launch 1 or 10 millions tasks, so (I assume) I cannot put them all in the queue... That's why I use a global executor in order to be able to always have some threads in queue (for that I cannot shutdown the executor, otherwise it's not usable anymore).</strong></p>
  
  <p>Latest code version:</p>
  
  <pre><code>    int dbOffset = 0;
      int nbOfArticlesPerRequest = 5; //100;
      int MYTHREADS = 2;
      int loopIndex = 0;
  
      ThreadPoolExecutor executorPool = new ThreadPoolExecutor(MYCORES, MYCORES, 0L,TimeUnit.MILLISECONDS, new LinkedBlockingQueue&lt;Runnable&gt;()); // **HERE IT WOULD BE A GLOBAL VARIABLE**
         while(bContinue) // in this loop we'll constantly fill the pool list
          {
              loopIndex++;
  
              List&lt;String&gt; ids = getIds(dbOffset, nbOfArticlesPerRequest ); // getIds(offset, rows_number)
               for(String id: ids) {
                      worker = new MyRunnable(id);
                      executorPool.execute(worker);
               }
  
              while (executorPool.getActiveCount() &gt;= MYTHREADS  || executorPool.getQueue().size()&gt; Math.max(1, MYTHREADS -2)) 
              {
                  System.out.println("Pool size is now " + executorPool.getActiveCount()+
                                          " - queue size: "+ executorPool.getQueue().size()
                  );
  
                  if(executorPool.getQueue().size() &lt;= Math.max(1, MYCORES-2)) {
                      System.out.println("Less than "+Math.max(1, MYCORES-2)+" threads in queue ---&gt; fill the queue");
                      break;
                  }
  
                  TimeUnit.MILLISECONDS.sleep(2000);
              }
  
              if(loopIndex&gt;=3) {
                  System.out.println("\nEnd the loop #"+loopIndex+" ===&gt; STOOOP!\n");
                  bContinue = false;
              }
              dbOffset+=nbOfArticlesPerRequest;
          }
  
      executorPool.shutdown();
      // Wait until all threads are finish
      while (!executorPool.isTerminated()) {
          System.out.println("Pool size is now " + executorPool.getActiveCount()+
                  " - queue size: "+ executorPool.getQueue().size()
          );
          TimeUnit.MILLISECONDS.sleep(500);
      }
  </code></pre>
  
  <p>Thanks in advance</p>