老大让把以前的定时改成固定延迟的策略,即把以前固定的15分钟执行的任务改成没15分钟执行一次,但是如果上一次在15分钟没执行完毕,就等它执行完毕再执行(别管什么任务居然可以执行15分钟.......是个javamail收信的问题,可能会卡收信好几天...一直找不到好的方法).查了下API,Time.schedule(TimerTask task, long delay, long period)好像可以做到,但是它的doc我貌似看不太明白,好吧,是这样的(我用的是
sun中文技术社区翻译的中文,我承认我英语没过4级):
-
安排指定的任务从指定的延迟后开始进行重复的
固定延迟执行。以近似固定的时间间隔(由指定的周期分隔)进行后续执行。
在固定延迟执行中,根据前一次执行的实际执行时间来安排每次执行。如果由于任何原因(如垃圾回收或其他后台活动)而延迟了某次执行,则后续执行也将被延迟。从长期来看,执行的频率一般要稍慢于指定周期的倒数(假定 Object.wait(long) 所依靠的系统时钟是准确的)。
固定延迟执行适用于那些需要“平稳”运行的重复活动。换句话说,它适用于在短期运行中保持频率准确要比在长期运行中更为重要的活动。这包括大多数动画任务,如以固定时间间隔闪烁的光标。这还包括为响应人类活动所执行的固定活动,如在按住键时自动重复输入字符。
-
-
参数:
-
task
- 所要安排的任务。 -
delay
- 执行任务前的延迟时间,单位是毫秒。 -
period
- 执行各后续任务之间的时间间隔,单位是毫秒。
抛出:
-
IllegalArgumentException
- 如果 delay 是负数,或者 delay + System.currentTimeMillis() 是负数。 -
IllegalStateException
- 如果已经安排或取消了任务,已经取消了计时器,或者计时器线程已终止。 -
- 在里面我没有看到我想要的:如果超过延迟了,是延迟后的时间加上执行间隔后执行还是立刻执行.
- 那就自己动手看看吧:
-
package com.hcycom.lan.test; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Random; import java.util.Timer; import java.util.TimerTask; public class DelayTest extends TimerTask { private Random d = new Random(System.currentTimeMillis()); private DateFormat df = new SimpleDateFormat("HH:mm:ss SSS"); @Override public void run() { System.out.println(df.format(new Date())); try { int i = d.nextInt(20000); Thread.sleep(i); System.out.println("sleep " + i); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { new Timer().schedule(new DelayTest(), 0, 10000); } }
- 以下是某次执行的结果:
- 16:19:34 203
- sleep 10294
- 16:19:44 500
- sleep 8147
- 16:19:54 515
- sleep 6900
- 16:20:04 515
- sleep 1135
- 16:20:14 515
- sleep 19364
- 16:20:33 875
-
-
- 结果很明显:
- 当任务执行时间超过设定的间隔时,在本次任务执行完毕后,将立刻执行下次任务,不会理睬间隔的.
- 当任务执行时间小于设定的间隔时,将按照间隔去执行.