java timer的使用问题 100分
本帖最后由 valid26 于 2012-11-12 11:42:55 编辑 下面一段代码 是要当前时间的第二天早上9点整 输出一句get in timer!!!!
可是我运行代码后,把系统时间调到第二天8点59分58秒,过了2秒什么反应也没有。
但是我把c.add(Calendar.DATE, 1);这句去掉,把系统时间改成8点59分45秒,再运行程序,过一会就输出了。
求大侠指点 急用 谢谢
public class Cs {
public static SimpleDateFormat sd = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
c.add(Calendar.DATE, 1);
c.set(Calendar.HOUR_OF_DAY, 9);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
Date time = c.getTime();
Timer timer = new Timer();
System.out.println("1: " + sd.format(time));
timer.schedule(new TimerTask() {
public void run() {
System.out.println("get in timer!!!!");
}
}, time);
}
}
[最优解释]
这个问题不好解决。。。
在Timer内部,它是先计算下一次任务距离现在还有多少毫秒,然后直接执行 Object.wait(毫秒数),这样就不需要频繁去检测现在时间跟任务时间的差距,节省开销。
而你修改系统时间,应该是不会影响这个passby的wait(毫秒数)的,否则时钟就全错乱了。
关键代码是:
private void mainLoop() {
while (true) {
try {
TimerTask task;
boolean taskFired;
synchronized(queue) {
// Wait for queue to become non-empty
while (queue.isEmpty() && newTasksMayBeScheduled)
queue.wait();
if (queue.isEmpty())
break; // Queue is empty and will forever remain; die
// Queue nonempty; look at first evt and do the right thing
long currentTime, executionTime;
task = queue.getMin(); // 得到最近所需执行的任务
synchronized(task.lock) {
if (task.state == TimerTask.CANCELLED) {
queue.removeMin();
continue; // No action required, poll queue again
}
currentTime = System.currentTimeMillis();
executionTime = task.nextExecutionTime;
if (taskFired = (executionTime<=currentTime)) { // 检查下是否需要发生
if (task.period == 0) { // Non-repeating, remove
queue.removeMin();
task.state = TimerTask.EXECUTED;
} else { // Repeating task, reschedule
queue.rescheduleMin(
task.period<0 ? currentTime - task.period
: executionTime + task.period);
}
}
}
if (!taskFired) // Task hasn't yet fired; wait // 还没需要发生则等毫秒数
queue.wait(executionTime - currentTime);
}
if (taskFired) // Task fired; run it, holding no locks // 这个是需要发生的
task.run();
} catch(InterruptedException e) {
}
}
}
所以你需要的是一种定期会检查当前时间跟任务时间的调度器,记得Quartz似乎支持这种。
[其他解释]
估计是你的测试方法不对,你可以试试真的等到第二天
[其他解释]
试试这个:
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, 9);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
Date time = new Date(c.getTime().getTime() + (1000 * 60 * 60 * 24));
// ...