我试图每三秒钟运行一次java.util.Timer
,并且在特定条件下需要将其再延迟2秒。为了检查是否可以使用Thread.sleep()
来实现,我在下面编写了代码。
Timer t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
if (true) { //When this is false timer should continue at 3 second interval.
try {
Thread.currentThread().sleep(2000); //Delay by another 2 seconds.
} catch (Exception ex) {
ex.printStackTrace();
}
}
System.out.println(new Date());
}
}, 0, 3000); //Trigger every 3 seconds.
我希望打印的时戳相差5秒。但是我得到了3秒的差异。
Tue Sep 18 15:08:17 IST 2018
Tue Sep 18 15:08:20 IST 2018
Tue Sep 18 15:08:23 IST 2018
Tue Sep 18 15:08:26 IST 2018
Tue Sep 18 15:08:29 IST 2018
我想念什么?
答案 0 :(得分:2)
您的2秒睡眠只是在TimerTask
触发器之间的3秒间隔内模拟2秒工作。因此,大约在睡眠后1秒钟,您的计时器将重新启动。
尝试睡眠5秒钟。
但是,请记住以这种方式进行延迟不是很稳定。计时器将考虑所有落后于计划的任务,并在前一个任务完成后顺序触发它们。如果您确实要这样做,最好取消任务并将它们重新安排为5秒间隔。
答案 1 :(得分:1)
您当前的代码只是将日期打印延迟2秒。仍将间隔3秒。
例如:以开始日期x:
没有Thread.sleep,您将在以下位置打印:
x, x + 3, x + 6, x + 9
使用Thread.sleep,您将在以下位置打印:
x + 2, x + 3 + 2, x + 6 + 2, x + 9 + 2
等于:
x + 2, x + 5, x + 8, x + 11 etc
所以每次打印之间还有3秒的延迟。
请参阅https://docs.oracle.com/javase/8/docs/api/java/util/Timer.html上的文档
与每个Timer对象相对应的是一个后台线程,该线程 用于依次执行所有计时器任务。计时器任务 应该很快完成。如果计时器任务花费大量时间 完成后,它将“占用”计时器的任务执行线程。这可以 反过来,延迟后续任务的执行,这可能会“束手无策” 并在(如果有问题的时候)快速连续执行 终于完成了。
同一线程将用于处理计时器任务的每次执行。当任务运行并且在计时器激发下一次执行任务之前未及时完成时,下一次执行将延迟到上一次执行完成为止。该行为类似于ScheduledThreadPoolExecutor,线程池大小为1。