• java.util.Timer用法须知


    项目中用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();//销毁的时候把这个任务取消,否者这个任务会一直存在这句代码。每次监听器销毁的时候也把这个定时任务给取消。

  • 相关阅读:
    初始Dubbo
    ProcessBuilder执行本地命令
    Deep Learning的基本思想
    机器学习(Machine Learning)
    Group By和Order By的总结
    Oracle sqlldr命令
    redis的简单操作
    Java程序中做字符串拼接时可以使用的MessageFormat.format
    Bean的作用域
    DI延伸
  • 原文地址:https://www.cnblogs.com/andysd/p/3003788.html
Copyright © 2020-2023  润新知