zoukankan      html  css  js  c++  java
  • 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();//销毁的时候把这个任务取消,否者这个任务会一直存在这句代码。每次监听器销毁的时候也把这个定时任务给取消。

  • 相关阅读:
    Laravel 集成 laravel Scout + Elasticsearch
    Vim Tab to Space and other configurations
    Gitlab To Gitlab 进行项目迁移
    win10 程序管理员权限读写文件和界面无法拖入的情况解决
    4.5 RNN循环神经网络(recurrent neural network)
    mumpy,h5py和tensorflow版本不匹配导致报错
    tensorflow预定义经典卷积神经网络和数据集tf.keras.applications
    QT失去focus后自动隐藏界面
    4.3CNN卷积神经网络最详细最容易理解--tensorflow源码MLP对比
    4.2tensorflow多层感知器MLP识别手写数字最易懂实例代码
  • 原文地址:https://www.cnblogs.com/andysd/p/3003788.html
Copyright © 2011-2022 走看看