title: ScheduledExecutorService Life Cycle?
body: <p>I have an object that needs to do periodically do some work while the object itself is alive, so I designed something like the following. Basically a Main class which contains a reference to a ScheduledExecutorService instance. In this example, all the periodical work is to print a string to std. </p>
  
  <p>I expect the code to behave like the following: </p>
  
  <ol>
  <li>test2 gets called, which create a Main object o1 (within it a ScheduledExecutorService). </li>
  <li>test2 register to print out a line every second on o1. </li>
  <li>test2 returns, o1 becomes garbage. </li>
  <li>System gc kicks in to gc o1, which has a finalize method to shutdown it's local scheduler. </li>
  </ol>
  
  <p>However, if I run this program, what happens is that it will go on FOREVER. Basically the gc never calls o1's finalizer and as a result, scheduler never shuts down and as a result, even when main thread end, the program still won't quit. </p>
  
  <p>Now if I comment out the o1.register in test2(), the program behaves like it should, e.g. gc called etc. Also in debugger it seems only after a call to ScheduledExecutorService.schedule will an actual thread created. </p>
  
  <p>Any explanation what's happening? </p>
  
  <pre><code>public class Main {
  
  public static void main(String[] args) throws Exception {
      test2();
  
      System.gc();
      System.out.println("Waiting for finalize to be called..");
      Thread.sleep(5000);
  }
  
  private static void test2() throws Exception {
      Main o1 = new Main();
      o1.register();
      Thread.sleep(5000);     
  }
  
  private final ScheduledExecutorService _scheduler = Executors.newSingleThreadScheduledExecutor();   
  
  private void register() {
      _scheduler.scheduleWithFixedDelay(new Runnable() { 
          @Override public void run() { 
              System.out.println("!doing stuff...");
              }
          }, 1, 1, TimeUnit.SECONDS);
  }
  
  @Override
  protected void finalize() throws Throwable  {
      try {
          System.out.print("bye");
          _scheduler.shutdown();          
      } finally {
          super.finalize();
      }       
  }
  </code></pre>
  
  <p>}</p>