2016-08-11 36 views
3

这里是我想要的代码:什么是java.util.Timer固定延迟周期性任务?

import java.util.Timer; 
import java.util.TimerTask; 

public class PeriodicTask { 

public static void main (String[] args) { 

    System.out.println("Main thread: " + Thread.currentThread()); 
    Timer timer = new Timer(); 
    final long start = System.currentTimeMillis(); 
    timer.schedule(new TimerTask() { 
     @Override 
     public void run() { 
      System.out.print("Timer task invoked in millis: " + 
              (System.currentTimeMillis()- start)); 
      System.out.println(" -- " + Thread.currentThread()); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      System.out.println("task finished "+(System.currentTimeMillis() 
           - start)); 
     } 
    }, 1000,500); 
} 
} 

输出:

Main thread: Thread[main,5,main] 
Timer task invoked in millis: 1000 -- Thread[Timer-0,5,main] 
task finished 2001 
Timer task invoked in millis: 2001 -- Thread[Timer-0,5,main] 
task finished 3002 
Timer task invoked in millis: 3002 -- Thread[Timer-0,5,main] 
task finished 4002 
Timer task invoked in millis: 4002 -- Thread[Timer-0,5,main] 
...... 

按照java.util.Timer中的文档所提供的时间段应该在每次任务执行分开。所以我期待每个钓鱼任务和新的被调用的任务应该分开500毫秒,例如在第一个任务结束和第二个任务执行开始之间应该是:

task finished 2001 
Timer task invoked in millis: **2501** -- Thread[Timer-0,5,main] 

我错过了什么吗?

我使用JDK 1.8

回答

0

分隔每个任务的period是不是相对于任务的结束,而是它的起点。 Timer将尝试在period过去之后再次安排任务。除非任务仍在运行,否则将在前一任务完成后立即安排。

在您给出的示例中,您设置了一个Timer,其中period的值为500ms。您在方法内为1000ms调用sleep()。这意味着Timer想要在半秒后再次安排任务,但不能完成,因为之前的任务仍有半秒钟才能完成。

+0

你的解释与我的输出非常一致。我猜Java文档写得非常糟糕。例如“在固定延迟执行中,每个执行都按照前一次执行的实际执行时间进行调度”。不知道他们想说什么。世界“执行”一次使用四次。 – Joe

+0

@Joe是的。我检查了java文档,也没有真正理解它,所以这就是为什么我设置了一些测试,并发现这是一致的。另外,如果你不能提出这个问题,你能否将其标记为正确的。 – Arthur

+0

当然,谢谢你的帮助! – Joe