您的位置:首页 > 编程语言 > Java开发

java.util.Timer用法须知

2013-04-07 12:35 316 查看
项目中用Timer做了定时任务,就是每天定时给某些特定的用户发送消息,可是不知道为什么,数据库中老是出现多条通知的情况,我刚开始是这样用Timer类的:

在监听器初始化中给这个Timer添加定时任务,然后就什么都不管了,结果就出现上面的情况,代码如下:

public class JobListener implements ServletContextListener {

//执行任务
private Timer timer = new Timer();

public void contextInitialized(ServletContextEvent arg0) {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date timerDate = sdf2.parse(sdf.format(new Date())+" 18:00:00");
if(date.after(timerDate)) { //今天18点过后
Calendar calendar = Calendar.getInstance();
calendar.setTime(timerDate);
calendar.add(Calendar.DATE, 1);
timerDate = calendar.getTime();
}
RemindBalanceTask rbt = new RemindBalanceTask(userService, notificationService);
timer.schedule(rbt, timerDate, (long)(24*60*60*1000));
System.out.println("添加了一个任务");
} catch (ParseException e) {
e.printStackTrace();
}
}
}
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("监听器销毁了~~~~~~~~~~~~~~~~~~~~~~~~~");
}

}


  

RemindBalanceTask 这个是执行代码的线程。


今天分析了一下可能出现了原因,分析到了项目会重启,然后监听器被再次初始化,这个时候定时任务的timer还在运行。于是就做了一个实验:

public class TestTimer extends TimerTask{

@Override
public void run() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("我被运行了:"+dateFormat.format(new Date()));
}

}

public class Main {
private Timer timer = new Timer();

public static void main(String[] args) {
Main main = new Main();
main.timer.schedule(new TestTimer(), new Date(),1000);
System.out.println("测试");
main.timer = null;
}

}


  测试结果出来了,出了main方法,照样打印,也就是即使把timer指向null了这个时候计划的任务仍然在运行,于是就改变了代码:

public class Main {
private Timer timer = new Timer();

public static void main(String[] args) {
Main main = new Main();
main.timer.schedule(new TestTimer(), new Date(),1000);
System.out.println("测试");
main.timer.cancel();
}

}


  这个时候跳出了main方法也就不打印了,哈哈,这下子项目中的问题就出现了,如果是多次重启项目而不是服务器的话,也就是监听器会被多次的重启,但是Timer始终不会消失,重启一次就多了一个Timer,这就是原因了,最后在监听器的销毁的方法中添加了this.timer.cancel();//销毁的时候把这个任务取消,否者这个任务会一直存在这句代码。每次监听器销毁的时候也把这个定时任务给取消。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: