title: ThreadPoolExecutor runs even after ScheduledFuture is cancelled
body: <p>I'm looking to create a ScheduledThreadPoolExecutor with an unknown pool size. Pool size is determined at run-time, will likely be between 1-5, and for this example I used size 2. We use a custom Task that simply executes a method every so often, but that method will eventually throw an exception (which I've simulated with a simple numTimes variable and if statement). If an exception is thrown, I only want to cancel execution of THAT specific thread! If all threads are cancelled, I want to shut down the ScheduledThreadPoolExecutor. Once numTimes == 5 I simulate the exception to cancel the thread), and I can manage to cancel the thread a number of ways but they just don't feel right.    </p>
  
  <p>As a side note, I placed ScheduledFuture everywhere just to play around with cancelling it. </p>
  
  <pre><code>    public class Test 
  {
    static ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(2);
  
    public static void main(String[] args) 
    { stpe.scheduleWithFixedDelay(new UpdateTask(1), 0, 1000, TimeUnit.MILLISECONDS);
      stpe.scheduleWithFixedDelay(new UpdateTask(2), 0, 5000, TimeUnit.MILLISECONDS);
  //    stpe.shutdown();
    }
  
    public static class UpdateTask implements Runnable
    {  
       int id;
       int numTimes = 0;
       ScheduledFuture&lt;?&gt; t;
  
       public UpdateTask(int id)
       { this.id = id;
       }
  
       public void run()
       { System.out.println("Hello " + id + " num: " + numTimes);
         String fn = "C:\\lib" + id;
         if (numTimes++ == 5)
         { File f = new File(fn);
           f.mkdir();
           t.cancel(false);
         }
       }
    }
  }
  </code></pre>
  
  <p>Calling t.cancel() from run() or from main() have the same effect, in that the thread stops executing but the program does not stop running. Naturally, this is because the ThreadPoolExecutor is still doing stuff, despite both threads no longer being scheduled.</p>
  
  <p>I tried invoking shutdown on stpe, but it doesn't finish thread execution. Two directories are created with stpe.shutdown commented out, and they are not otherwise.   </p>
  
  <p><strong>I can't figure out an elegant way to cancel ScheduledFuture, then ScheduledThreadPoolExecutor when all ScheduledFuture's are cancelled.</strong> </p>
  
  <h2>Final approach ##</h2>
  
  <p>I was not able to get s1.get() to work as described in the answer below, so I simply created my own class to handle it. </p>
  
  <pre><code>public class Test 
  {
    static ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(2);
    static CancelUpdateTasks canceller;
  
    public static void main(String[] args) 
    { Test t = new Test();
      canceller.add(0, stpe.scheduleWithFixedDelay(new UpdateTask(0), 0, 1000, TimeUnit.MILLISECONDS));
      canceller.add(1, stpe.scheduleWithFixedDelay(new UpdateTask(1), 0, 5000, TimeUnit.MILLISECONDS));
      canceller.waitForSchedules();
      stpe.shutdown();
    }
  
    public Test() 
    { canceller = new CancelUpdateTasks();
    }
  
    public static class UpdateTask implements Runnable
    {  
       int id;
       int numTimes = 0;
  
       public UpdateTask(int id)
       { this.id = id;
       }
  
       public void run()
       { System.out.println("Hello " + id + " num: " + numTimes);
         if (numTimes++ == 5)
         { canceller.cancel(id);
         }
       }
    }
  
    public class CancelUpdateTasks 
    { List&lt;ScheduledFuture&lt;?&gt;&gt; scheduler;
      boolean isScheduled;
  
      public CancelUpdateTasks() 
      { scheduler = new ArrayList&lt;ScheduledFuture&lt;?&gt;&gt;();
        isScheduled = false;
      }
  
      public void waitForSchedules() 
      { int schedId = 0;
        while(isScheduled)
        { ScheduledFuture&lt;?&gt; schedule = scheduler.get(schedId);
          if (schedule.isCancelled())
          { if (schedId == scheduler.size() - 1)
              return;
            schedId++;
          }
          else
          { try 
            { Thread.sleep(1000);
            } 
            catch (InterruptedException e) 
            { e.printStackTrace();
            }
          }
        }
      }
  
      public void add(int id, ScheduledFuture&lt;?&gt; schedule) 
      { scheduler.add(id, schedule);
        if (!isScheduled)
          isScheduled = true;
      }
  
      public void cancel(int id)
      { scheduler.get(id).cancel(false);
      }
  
      public void cancelNow(int id)
      { scheduler.get(id).cancel(true);
      }
    }
  }
  </code></pre>