title: Java Timer/ScheduledExecutor appears to have a minimum resolution of 10 milliseconds
body: <p>I'm trying to schedule a task with a fixed-delay repetition, where the delay is 1 millisecond, and it appears that with both the <code>Timer</code> and the <code>ScheduledThreadPoolExecutor</code> classes, the best I can do is 10 millseconds.  I'm not expecting to get exactly 1 millisecond resolution, but I wasn't expecting an almost perfect 10 millisecond resolution.  Here's a simple class that I put together to test what's going on:</p>
  
  <pre><code>import java.util.concurrent.ScheduledThreadPoolExecutor;
  import java.util.concurrent.TimeUnit;
  import java.text.SimpleDateFormat;
  import java.util.Date;
  import java.util.Timer;
  import java.util.TimerTask;
  
  public class SchedTest
  {
      private static final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
      public static void main(String[] args)
      {
          int type = Integer.parseInt(args[0]);
          switch(type)
          {
              case 0:
                  ScheduledThreadPoolExecutor e = new ScheduledThreadPoolExecutor(1);
                  e.scheduleWithFixedDelay(new Runnable()
                          {
                              @Override
                              public void run()
                              {
                                  System.out.println("executor " + sdf.format(new Date()));
                              }
                          }, 0, 1, TimeUnit.MILLISECONDS);
                  break;
  
              case 1:
                  Timer t = new Timer();
                  TimerTask task = new TimerTask()
                  {
                      @Override
                      public void run()
                      {
                          System.out.println("timer " + sdf.format(new Date()));
                      }
                  };
                  t.schedule(task, new Date(), 1);
                  break;
  
              case 2:
                  Thread th = new Thread()
                  {
                      @Override
                      public void run()
                      {
                          while(true)
                          {
                              System.out.println("thread " + sdf.format(new Date()));
                              try
                              {
                                  Thread.sleep(1);
                              }
                              catch(Exception e)
                              {
                                  //
                              }
                          }
                      }
                  };
                  th.start();
                  break;
          }
      }
  }
  </code></pre>
  
  <p>The output that I get from this class looks like this:</p>
  
  <pre><code>executor 11:52:05.202
  executor 11:52:05.212
  executor 11:52:05.222
  executor 11:52:05.232
  executor 11:52:05.242
  executor 11:52:05.252
  executor 11:52:05.262
  executor 11:52:05.272
  executor 11:52:05.282
  executor 11:52:05.292
  executor 11:52:05.302
  
  timer 11:52:08.009
  timer 11:52:08.019
  timer 11:52:08.029
  timer 11:52:08.039
  timer 11:52:08.049
  timer 11:52:08.059
  timer 11:52:08.069
  timer 11:52:08.079
  timer 11:52:08.089
  timer 11:52:08.099
  timer 11:52:08.109
  
  thread 11:52:13.020
  thread 11:52:13.021
  thread 11:52:13.022
  thread 11:52:13.023
  thread 11:52:13.024
  thread 11:52:13.025
  thread 11:52:13.026
  thread 11:52:13.027
  thread 11:52:13.028
  thread 11:52:13.029
  thread 11:52:13.030
  </code></pre>
  
  <p>My understanding of the fixed-delay is that the time between two executions of the task should be timeTakenByTask + delay - so I'm not sure how that's adding up to 10 milliseconds.  What am I missing here?  </p>
  
  <p>I'm running with JDK 1.8.0_131 on a Windows 7 laptop.</p>
  
  <p><em>Edit</em>
  If I run the following:</p>
  
  <pre><code>for(int x = 0;x &lt; 10000;x++)
  {
      System.out.println(System.currentTimeMillis());
  }
  </code></pre>
  
  <p>The output that I get is almost always at a 10ms resolution: that is, my output looks like the following numbers (repeated several times):
  1</p>
  
  <pre><code>516212971144
  1516212971144
  1516212971144
  ...
  1516212971154
  1516212971154
  1516212971154
  ...
  1516212971164
  1516212971164
  1516212971164
  ...
  1516212971174
  etc.
  </code></pre>
  
  <p>If I run long enough, occasionally I'll get one response that is actually 1ms between them, but 99% of the time, when the number changes it does so in 10ms increments.  So I think that @VGR has it right: as <code>Timer</code> seems to be using <code>System.currentTimeMillis()</code> to keep track of time - and it's likely that <code>ScheduledThreadPoolExecutor</code> is as well - the granularity of that call determines how often the tasks can execute, and as @VGR noted, the docs say that granularity can vary.  My machine must be one that has a 10ms granularity.</p>