timer_timertask - CSDN
timer 订阅
Timer
信息
操作系统
未知
开发语言
开源协议
未知
Timer
Timer is an extension that is loosely based on Prototype's PeriodicalExecuter . The three main enhancements are: * It's for jQuery (1.1.x and 1.2.x) * Timer intervals can be reset during the event * It's a much shorter name
收起全文
精华内容
参与话题
  • Timer定时器用法详解

    万次阅读 2019-07-20 21:36:21
    Timer timer = new Timer(); //其中会调用this("Timer-" + serialNumber());, 即它以Timer+序列号为该定时器的名字 Timer timer = new Timer(String name); //以name作为该定时器的名字 Timer time...

    先看API和结论:

    /**
        timer总结:
        Timer timer = new Timer();    //其中会调用this("Timer-" + serialNumber());, 即它以Timer+序列号为该定时器的名字
        Timer timer = new Timer(String name);    //以name作为该定时器的名字
        Timer timer = new Timer(boolean isDeamon);    //是否将此定时器作为守护线程执行
        Timer timer = new Timer(name, isDeamon);    //定时器名字, 是否为守护线程
        
        注意:
        默认无参构造器将会使该线程作为非守护线程, 即使主线程已经停止并销毁, 只要该线程还存在, 则程序不会停止
        即下面的所有执行的任务, 无论是否是定时还是非定时, 只要主线程一旦结束, 那么该定时器立即同主线程一起销毁
        
        以下所有的task都是TimerTask的子类
        所有time都是Date类型的日期
        所有delay和period都是long类型的延迟时间, 单位为毫秒
        timer.schedule(task, time);                    在time时间执行task任务1次
        timer.schedule(task, delay);                在延迟delay毫秒后执行task任务1次
        timer.schedule(task, firstTime, period);    在firsttime时间执行task1次,之后定期period毫秒时间执行task,    时间如果为过去时间, 不会执行过去没有执行的任务, 但是会马上执行
        timer.schedule(task, delay, period);        在延迟delay后执行task1次,之后定期period毫秒时间执行task,     时间如果为过去时间, 不会执行过去没有执行的任务, 但是会马上执行
        
        timer.scheduleAtFixedRate(task, firstTime, period);        在firstTime时间执行task一次, 以后每隔period毫秒执行1次, 时间如果为过去时间, 会执行过去没有执行的任务, 但是会马上执行
        timer.scheduleAtFixedRate(task, delay, period);            在delay毫秒后执行task一次, 以后每隔period毫秒执行1次, 时间如果为过去时间, 会执行过去没有执行的任务, 但是会马上执行
        
        区别:test4();
        timer.schedule(task, firstTime, period);
        timer.scheduleAtFixedRate(task, firstTime, period);
        从test4运行结果可以看到, 如果开始时间在过去, 则
            schedule会表现出只从当前时间开始,
            scheduleAtFixedRate会把之前没有来得及执行的任务全都执行, 感觉像之前一直有在执行一样
            
        区别: test5()
        timer.schedule(task, time);
        timer.schedule(task, delay);
        其中, 如果time时间为过去时间, 则该任务会马上执行, 如果为将来时间, 则会等待时间到来再执行
        如果传入的是delay, 则delay不可以为负数, 负数报错, 正数代表未来的delay毫秒以后执行
        
        
        小结:
            时间如果为过去时间, 则所有scheduke和scheduleAtFixedRate都会立即执行
            并且scheduke不会执行过去的任务, 而scheduleAtFixedRate则会把过去的任务全都执行, 即按照固定时间执行一样
            isDeamon决定是否该Timer以守护线程存在

        timer.purge();
        先看英文描述:
        Removes all cancelled tasks from this timer's task queue. Calling this method has no effect on the behavior of the timer, but eliminates the references to the cancelled tasks from the queue. If there are no external references to these tasks, they become eligible for garbage collection. 
        Most programs will have no need to call this method. It is designed for use by the rare application that cancels a large number of tasks. Calling this method trades time for space: the runtime of the method may be proportional to n + c log n, where n is the number of tasks in the queue and c is the number of cancelled tasks. 
        Note that it is permissible to call this method from within a a task scheduled on this timer.
        Returns:
        the number of tasks removed from the queue.
        Since:
        1.5
        即purge();对实际的timer的任务执行不会有影响, 它仅仅只会移除所有被取消的任务队列的引用以方便垃圾回收, 通常不用调用此方法, 只有任务数非常多(n + c log n)的时候, 可以调用此方法以时间换取空间.
        
        timer.cancel();
        Terminates this timer, discarding any currently scheduled tasks. Does not interfere with a currently executing task (if it exists). Once a timer has been terminated, its execution thread terminates gracefully, and no more tasks may be scheduled on it. 
        Note that calling this method from within the run method of a timer task that was invoked by this timer absolutely guarantees that the ongoing task execution is the last task execution that will ever be performed by this timer. 
        This method may be called repeatedly; the second and subsequent calls have no effect.
        即cancel();停止该timer, 并且丢弃所有绑定的任务, 但不干预当前正在执行的任务。一旦timer停止了, 那么其执行线程将会优雅终止, 并且该timer不可以再绑定task任务了
     */

    再看测试代码:

    import java.util.Calendar;
    import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask;
    /**
    	timer总结:
    	Timer timer = new Timer();	//其中会调用this("Timer-" + serialNumber());, 即它以Timer+序列号为该定时器的名字
    	Timer timer = new Timer(String name);	//以name作为该定时器的名字
    	Timer timer = new Timer(boolean isDeamon);	//是否将此定时器作为守护线程执行
    	Timer timer = new Timer(name, isDeamon);	//定时器名字, 是否为守护线程
    	
    	注意:
    	默认无参构造器将会使该线程作为非守护线程, 即使主线程已经停止并销毁, 只要该线程还存在, 则程序不会停止
    	即下面的所有执行的任务, 无论是否是定时还是非定时, 只要主线程一旦结束, 那么该定时器立即同主线程一起销毁
    	
    	以下所有的task都是TimerTask的子类
    	所有time都是Date类型的日期
    	所有delay和period都是long类型的延迟时间, 单位为毫秒
    	timer.schedule(task, time);					在time时间执行task任务1次
    	timer.schedule(task, delay);				在延迟delay毫秒后执行task任务1次
    	timer.schedule(task, firstTime, period);	在firsttime时间执行task1次,之后定期period毫秒时间执行task,	时间如果为过去时间, 不会执行过去没有执行的任务, 但是会马上执行
    	timer.schedule(task, delay, period);		在延迟delay后执行task1次,之后定期period毫秒时间执行task, 	时间如果为过去时间, 不会执行过去没有执行的任务, 但是会马上执行
    	
    	timer.scheduleAtFixedRate(task, firstTime, period);		在firstTime时间执行task一次, 以后每隔period毫秒执行1次, 时间如果为过去时间, 会执行过去没有执行的任务, 但是会马上执行
    	timer.scheduleAtFixedRate(task, delay, period);			在delay毫秒后执行task一次, 以后每隔period毫秒执行1次, 时间如果为过去时间, 会执行过去没有执行的任务, 但是会马上执行
    	
    	区别:test4();
    	timer.schedule(task, firstTime, period);
    	timer.scheduleAtFixedRate(task, firstTime, period);
    	从test4运行结果可以看到, 如果开始时间在过去, 则
    		schedule会表现出只从当前时间开始,
    		scheduleAtFixedRate会把之前没有来得及执行的任务全都执行, 感觉像之前一直有在执行一样
    		
    	区别: test5()
    	timer.schedule(task, time);
    	timer.schedule(task, delay);
    	其中, 如果time时间为过去时间, 则该任务会马上执行, 如果为将来时间, 则会等待时间到来再执行
    	如果传入的是delay, 则delay不可以为负数, 负数报错, 正数代表未来的delay毫秒以后执行
    	
    	
    	小结:
    		时间如果为过去时间, 则所有scheduke和scheduleAtFixedRate都会立即执行
    		并且scheduke不会执行过去的任务, 而scheduleAtFixedRate则会把过去的任务全都执行, 即按照固定时间执行一样
    		isDeamon决定是否该Timer以守护线程存在
    
    	timer.purge();
    	先看英文描述:
    	Removes all cancelled tasks from this timer's task queue. Calling this method has no effect on the behavior of the timer, but eliminates the references to the cancelled tasks from the queue. If there are no external references to these tasks, they become eligible for garbage collection. 
    	Most programs will have no need to call this method. It is designed for use by the rare application that cancels a large number of tasks. Calling this method trades time for space: the runtime of the method may be proportional to n + c log n, where n is the number of tasks in the queue and c is the number of cancelled tasks. 
    	Note that it is permissible to call this method from within a a task scheduled on this timer.
    	Returns:
    	the number of tasks removed from the queue.
    	Since:
    	1.5
    	即purge();对实际的timer的任务执行不会有影响, 它仅仅只会移除所有被取消的任务队列的引用以方便垃圾回收, 通常不用调用此方法, 只有任务数非常多(n + c log n)的时候, 可以调用此方法以时间换取空间.
    	
    	timer.cancel();
    	Terminates this timer, discarding any currently scheduled tasks. Does not interfere with a currently executing task (if it exists). Once a timer has been terminated, its execution thread terminates gracefully, and no more tasks may be scheduled on it. 
    	Note that calling this method from within the run method of a timer task that was invoked by this timer absolutely guarantees that the ongoing task execution is the last task execution that will ever be performed by this timer. 
    	This method may be called repeatedly; the second and subsequent calls have no effect.
    	即cancel();停止该timer, 并且丢弃所有绑定的任务, 但不干预当前正在执行的任务。一旦timer停止了, 那么其执行线程将会优雅终止, 并且该timer不可以再绑定task任务了
    	
    	
     */
    public class TimerTest {
    
    	public static void main(String[] args) {
    //		test1();		//测试schedule功能
    //		test2();		//测试所有scheduleAtFixedRate功能
    //		test3();		//测试isDeamon对Timer的影响
    //		test4();		//测试AtFixedRateSchedule和schedule区别
    //		test5();		//测试schedule在过去时间的表现, 如果firstTime是过去时间, 则立即执行, 如果是未来时间, 则会等待时间到之后执行, 如果是传入延迟时间, 则延迟时间不能为负数, 否则报错
    //		test6();		
    		test7();
    	}
    	
    	public static void test1()
    	{
    		Timer timer = new Timer();
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("执行了1次");
    			}
    		}, 1000);
    		
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("执行了2次");
    			}
    		}, getDelayTime(2));
    		
    		//第3和第4个task的执行顺序是不确定的,因为时间片的切换导致的微小差别
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("执行了3次");
    			}
    		}, getDelayTime(3), 1000);	//3, -3
    		
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.err.println("执行了4次");
    			}
    		}, 1000, 1000);
    	}
    	public static void test2()
    	{
    		Timer timer = new Timer();
    		timer.scheduleAtFixedRate(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("AtFixedRate1");
    			}
    		}, getDelayTime(1), 1000);
    		
    		timer.scheduleAtFixedRate(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("AtFixedRate2");
    			}
    		}, 2000, 1000);
    	}
    	
    	public static void test3()
    	{
    		Timer timer = new Timer("isDeamon", true);
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("isDeamon");
    				try {
    					Thread.sleep(10000);
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}, getDelayTime(2), 2000);
    	}
    	
    	public static void test4()
    	{
    		Timer timer = new Timer("AtFixedRate", false);
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("schedule");
    			}
    		}, getDelayTime(-5), 2000);
    		
    		timer.scheduleAtFixedRate(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("scheduleAtFixedRate");
    			}
    		}, getDelayTime(-5), 2000);
    	}
    	
    	public static void test5()
    	{
    		Timer timer = new Timer();
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("测试时间为过去时间和将来时间对schedule的影响");
    			}
    		}, getDelayTime(-5));	//立即执行
    	}
    	
    	public static void test6()
    	{
    		//purge: 清洗, 净化
    		Timer timer = new Timer();
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("测试purge1");
    			}
    		}, getDelayTime(1), 1000);
    		System.out.println("purge: "+timer.purge());
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("测试purge2");
    			}
    		}, getDelayTime(1), 1000);
    	}
    	
    	public static void test7()
    	{
    		//将7和6对比看
    		Timer timer = new Timer();
    		class MyTimerTask extends TimerTask{
    			@Override
    			public void run() {
    				System.out.println("测试purge1");
    				this.cancel();
    			}
    		}
    		for(int i = 0; i<100; i++)
    		{
    			MyTimerTask mt = new MyTimerTask();
    			timer.schedule(mt, getDelayTime(1), 1000);
    			mt.cancel();
    		}
    //		timer.cancel();
    		System.out.println("此时可以移除取消的任务数为100个: "+timer.purge());
    		/*timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("我现在还可以执行~~");
    			}
    		}, getDelayTime(2));*/
    		
    		
    		for(int i = 0; i<100; i++)
    		{
    			MyTimerTask mt = new MyTimerTask();
    			mt.cancel();
    			timer.schedule(mt, getDelayTime(1), 1000);
    		}
    		System.out.println("此时可以移除取消的任务数为100个: "+timer.purge());
    		///
    	}
    	
    	//给定一个时间,返回给定多久以后的Date
    	public static Date getDelayTime(int howlong)
    	{
    		Calendar cld = Calendar.getInstance();
    		cld.set(Calendar.SECOND, howlong+cld.get(Calendar.SECOND));
    		return cld.getTime();
    	}
    }
    

    其中难点只有这个purge的使用,下面这篇文章详细解释了purge在queue队列非常大时如何避免内存泄漏的

    Java定时任务Timer调度器【三】 注意事项(任务精确性与内存泄漏)

    这里有个问题待考虑:为什么purge()返回值一直是0,我已经将TimerTask任务取消,但是返回的purge()还是0.这点很奇怪。

    其他类似文章:

    定时器Timer

    展开全文
  • Timer

    2020-06-01 21:50:26
    定时器Timer--内部使用多线程方式处理 在指定的时间开始执行某一个任务;执行计划任务的代码要放入TimerTask的子类中(需要执行具体的什么任务放在这块),因为TimerTask是一个抽象类 1:schedule(TimerTask task,Date...

    简介:

           定时器Timer是一种定时器工具,用来在一个后台线程计划执行指定任务。它可以计划执行一个任务一次或反复多次。TimerTask是一个抽象类,它的子类代表一个可以被Timer计划的任务。

           定时器Timer内部使用多线程方式处理。

    Timer方法介绍:

           1:schedule(TimerTask task,Date time)在指定的日期执行一次某一任务,试运行代码如下:

    public class MyTask extends TimerTask{
    	public void run(){
    		System.out.println("我是需要执行的定时任务"+new Date());
    	}
    	public static void main(String args[]){
    		System.out.println("当前时间为"+new Date());
    		Calendar calendar = Calendar.getInstance();
    		/*执行完当前时间之后,未来的10s执行*/
    		calendar.add(Calendar.SECOND,10);
    		Date date = calendar.getTime();
    
    		MyTask task = new MyTask();
    		Timer timer = new Timer();
    		timer.schedule(task,date);
    	}
    }

           输出结果如下所示,我们发现eclipse的任务还未销毁,呈红色状态,因为创建一个Timer就是启动一个线程,这个线程不是守护线程,所以会一直运行;如果将Timer改成守护线程即:Timer timer = new Timer(true)。则打印完当前时间就停止了,不会执行task的任务。如果有多个TimerTask任务及延时测试,则以队列的方式一个一个被顺序性地执行,因为前面的任务有可能消耗的时间较长,所以执行的时间和预期的时间很可能不一致。

           2:schedule(TimerTask task,Date firstTime,long period) 在指定的日期之后按指定的间隔周期,无限循环的执行某一任务,试运行代码如下:

    public class MyTask extends TimerTask{
    	public void run(){
    		System.out.println("我是需要执行的定时任务"+new Date());
    	}
    	public static void main(String args[]){
    		System.out.println("当前时间为"+new Date());
    		Calendar calendar = Calendar.getInstance();
    		calendar.add(Calendar.SECOND,10);//执行完当前时间之后,未来的10s执行
    		Date date = calendar.getTime();
    
    		MyTask task = new MyTask();
    		Timer timer = new Timer();
    		timer.schedule(task,date,4000);
    	}
    }

           输出结果如下:

           3:cancel() 将自身从任务队列中进行清除,试运行代码如下:

    public class MyTask extends TimerTask{
    	public void run(){
    		System.out.println("我是需要执行的定时任务"+new Date());
    		this.cancel();
    		System.out.println("我已经移除了自己的定时任务");
    	}
    	public static void main(String args[]){
    		System.out.println("当前时间为"+new Date());
    		Calendar calendar = Calendar.getInstance();
    		Date date = calendar.getTime();
    
    		MyTask task = new MyTask();
    		Timer timer = new Timer();
    		timer.schedule(task,date,4000);
    	}
    }

           输出结果如下,我们发现:代码则只执行一次,就不在循环执行了,其他的TimerTask不受任何影响。

           4:使用cancle()方法将任务队列中全部的任务进行清空,试运行代码如下:

    public class MyTaskB extends TimerTask{
    	public void run(){
    		System.out.println("我是需要执行的定时任务B"+new Date());
    	}
    }
    public class MyTaskA extends TimerTask{
    	public void run(){
    		System.out.println("我是需要执行的定时任务A"+new Date());
    	}
    	public static void main(String args[]){
    		System.out.println("当前时间为"+new Date());
    		Calendar calendar = Calendar.getInstance();
    		Date date = calendar.getTime();
    
    		MyTaskA taskA = new MyTaskA();
    		MyTaskB taskB = new MyTaskB();
    		Timer timer = new Timer();
    		timer.schedule(taskA,date,4000);
    		timer.schedule(taskB,date,4000);
    		try {
    			Thread.sleep(10000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		timer.cancel();
    	}
    }

           输出结果如下,我们发现程序只执行10s的循环任务,然后全部任务被清除,并且进程被销毁,按钮由红色变为灰色。

           注意:Timercancel()方法有时不一定会停止计划任务,而是正常执行;因为canel()方法有时没有争抢到queue锁,则让
    TimerTask类中的任务正常执行。

           5:schedule(TimerTask task,long delay) 以执行此方法当前的时间为参考时间,在此时间的基础上延迟指定的毫秒数后执行一次TimerTask任务,试运行代码如下:

    public class MyTaskA extends TimerTask{
    	public void run(){
    		System.out.println("我是需要执行的定时任务A"+new Date());
    	}
    	public static void main(String args[]){
    		MyTaskA taskA = new MyTaskA();
    		Timer timer = new Timer();
    		System.out.println("当前时间为"+new Date());
    		/*任务被延迟7s执行了*/
    		timer.schedule(taskA,7000);
    		
    	}
    }

           输出结果如下,我们发现,任务呗延迟7s执行了。

           6:schedule(TimerTask task,long delay,long period) 以执行此方法当前的时间为参考时间,在此时间的基础上延迟指定的毫秒数后执行一次TimerTask任务,再以某一时间间隔无限次的执行某一任务,试运行代码如下:

    public class MyTaskA extends TimerTask{
    	public void run(){
    		System.out.println("我是需要执行的定时任务A"+new Date());
    	}
    	public static void main(String args[]){
    		MyTaskA taskA = new MyTaskA();
    		Timer timer = new Timer();
    		System.out.println("当前时间为"+new Date());
    		timer.schedule(taskA,7000,1000);
    	}
    }

           输出结果如下,我们发现在延迟了7s之后,任务以1s为时间间隔依次执行。

           7:scheduleAtFixedRate(TimerTask task,Date firstTime,long period)  此方法和schedule()方法都会顺序的执行,只是scheduleAtFixedRate具有追赶性,试运行代码如下:

           schedule()方法情况一:MyTask里面睡1s,主线程timer.schedule(task,马上,3000),没有延时,第一次马上执行,第二次粗略的认为3s执行一次。

    public class MyTaskA extends TimerTask{
    	public void run(){
    		System.out.println("我是需要执行的定时任务A"+new Date());
    	}
    	public static void main(String args[]){
    		MyTaskA taskA = new MyTaskA();
    		Timer timer = new Timer();
    		System.out.println("当前时间为"+new Date());
    		try {
    			Thread.sleep(1000);
    			timer.schedule(taskA,0,3000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }

           schedule()方法情况二:MyTask里面睡1s,主线程timer.schedule(task,3000,4000),没有延时,第一次延迟3s执行, 第二次4s后执行。

    public class MyTaskA extends TimerTask{
    	public void run(){
    		System.out.println("我是需要执行的定时任务A"+new Date());
    	}
    	public static void main(String args[]){
    		MyTaskA taskA = new MyTaskA();
    		Timer timer = new Timer();
    		System.out.println("当前时间为"+new Date());
    		try {
    			Thread.sleep(1000);
    			timer.schedule(taskA,3000,4000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }

           schedule()方法情况三:MyTask里面睡5s,主线程timer.schedule(task,马上,2000),有延时,第一次马上执行,第二次5s后执行

    public class MyTaskA extends TimerTask{
    	public void run(){
    		System.out.println("我是需要执行的定时任务A"+new Date());
    	}
    	public static void main(String args[]){
    		MyTaskA taskA = new MyTaskA();
    		Timer timer = new Timer();
    		System.out.println("当前时间为"+new Date());
    		try {
    			Thread.sleep(5000);
    			timer.schedule(taskA,0,2000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }

           schedule()方法情况四:MyTask里面睡5s,主线程timer.schedule(task,3000,2000),有延时,第一次延迟3s执行,第二次5s后执行。

    public class MyTaskA extends TimerTask{
    	public void run(){
    		System.out.println("我是需要执行的定时任务A"+new Date());
    	}
    	public static void main(String args[]){
    		MyTaskA taskA = new MyTaskA();
    		Timer timer = new Timer();
    		System.out.println("当前时间为"+new Date());
    		try {
    			Thread.sleep(5000);
    			timer.schedule(taskA,3000,2000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }

           scheduleAtFixedRate()方法情况一:MyTask里面睡1s,主线程timer.scheduleAtFixedRate(task,马上,3000),没有延时,第一次马上执行,第二次粗略的认为3s执行一次。

    public class MyTaskA extends TimerTask{
    	public void run(){
    		System.out.println("我是需要执行的定时任务A"+new Date());
    	}
    	public static void main(String args[]){
    		MyTaskA taskA = new MyTaskA();
    		Timer timer = new Timer();
    		System.out.println("当前时间为"+new Date());
    		try {
    			Thread.sleep(1000);
    			timer.scheduleAtFixedRate(taskA,0,3000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }

           scheduleAtFixedRate()方法情况二:MyTask里面睡1s,主线程timer.scheduleAtFixedRate(task,3000,4000),没有延时,第一次延迟3s执行, 第二次4s后执行。

    public class MyTaskA extends TimerTask{
    	public void run(){
    		System.out.println("我是需要执行的定时任务A"+new Date());
    	}
    	public static void main(String args[]){
    		MyTaskA taskA = new MyTaskA();
    		Timer timer = new Timer();
    		System.out.println("当前时间为"+new Date());
    		try {
    			Thread.sleep(1000);
    			timer.scheduleAtFixedRate(taskA,3000,4000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }

           scheduleAtFixedRate​​​​​​​()方法情况三:MyTask里面睡5s,主线程timer.scheduleAtFixedRate(task,马上,2000),有延时,第一次马上执行,第二次5s后执行。

    public class MyTaskA extends TimerTask{
    	public void run(){
    		System.out.println("我是需要执行的定时任务A"+new Date());
    	}
    	public static void main(String args[]){
    		MyTaskA taskA = new MyTaskA();
    		Timer timer = new Timer();
    		System.out.println("当前时间为"+new Date());
    		try {
    			Thread.sleep(5000);
    			timer.scheduleAtFixedRate(taskA,0,2000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }

           scheduleAtFixedRate​​​​​​​()方法情况四:MyTask里面睡5s,主线程timer.scheduleAtFixedRate(task,3000,2000),有延时,第一次延迟3s执行,第二次5s后执行。

    public class MyTaskA extends TimerTask{
    	public void run(){
    		System.out.println("我是需要执行的定时任务A"+new Date());
    	}
    	public static void main(String args[]){
    		MyTaskA taskA = new MyTaskA();
    		Timer timer = new Timer();
    		System.out.println("当前时间为"+new Date());
    		try {
    			Thread.sleep(5000);
    			timer.scheduleAtFixedRate(taskA,3000,2000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }

           总结:这两个方法在运行效果上没有任何区别,但是schedule()方法没有追赶性,scheduleAtFixedRate()方法具有追赶性。

    public class MyTask extends TimerTask{
    	public void run() {
    		System.out.println("begin任务,我的执行时间为"+System.currentTimeMillis());
    		System.out.println("end任务,  我的执行时间为"+System.currentTimeMillis());
    	}
    
    	public static void main(String[] args) {
    		MyTask myTask = new MyTask();
    		System.out.println("现在执行时间为"+System.currentTimeMillis());
    		Calendar c = Calendar.getInstance();
    		c.set(Calendar.SECOND, c.get(Calendar.SECOND)-20);
    		System.out.println("计划执行时间为"+c.getTime().getTime());
    		Timer timer = new Timer();
    		/*因为需要提前执行,中间有20s的时间差,如果是schelude()方法,则这时间段的任务就不执行了,直接从当前时间开始往下执行*/
    		timer.schedule(myTask,c.getTime(), 1000);
    		
    		/*scheduleAtFixedRate方法则要追赶这20s的时间差,以当前时间执行好多次,即时间相同的任务,然后继续往下执行*/
    		timer.scheduleAtFixedRate(myTask,c.getTime(), 1000);
    		
    	}
    }

     

    展开全文
  • Timer用法

    千次阅读 2018-07-17 16:12:49
    项目需要,学了一下timer控件,很好用,特此分享。。。 以下是项目界面,详设,以及代码截图 1.项目界面截图 2.详设截图 3.数据和刷新时间代码截图 4.滚动状态代码截图 5.停止滚动代码截图 6.停止取样代码 7....

    项目需要,学了一下timer控件,很好用,特此分享。。。

    以下是项目界面,详设,以及代码截图

    1.项目界面截图


    这里写图片描述

    2.详设截图


    这里写图片描述

    3.数据和刷新时间代码截图


    这里写图片描述

    4.滚动状态代码截图


    这里写图片描述

    5.停止滚动代码截图


    这里写图片描述

    6.停止取样代码


    这里写图片描述

    7.设置刷新时间


    这里写图片描述

    8.双击触发方法


    这里写图片描述

    设计代码(方便你我他)


     /// <summary>
            /// 叶航宇
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
    
            string nowTimeYe = "";
            private void FormScheduleTracking_Load(object sender, EventArgs e)
            {
                //timer1.Interval = 1000;
                RefreshData();
            }
            /// <summary>
            /// 查询数据+刷新时间
            /// </summary>
            private void RefreshData()
            {
                DataSet dsPackageInventoryIn = PackageManageAPI.PackageManageService.GetLookYe();
                dsTv_Irder_Ianufacture_Info1.Merge(dsPackageInventoryIn);
                nowTimeYe = System.DateTime.Now.ToString();
                labDateTime.Text = nowTimeYe;
    
            }
    
            /// <summary>
            /// 设置按钮
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnSetting_Click(object sender, EventArgs e)
    
            {
                setWindowYe swy = null;
                if (swy == null || swy.IsDisposed)
                {
                    swy = new setWindowYe();
                    swy.Show();
                    this.RefreshData();
                }
                else { 
                swy.Activate();
                }
            }
            /// <summary>
            /// 停止滚动
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnStopspeed_Click(object sender, EventArgs e)
            {
                if (timer2.Enabled == true)//状态切换
                {
                    timer2.Enabled = false;
                    btnStopspeed.Text = "滚动";
                }
                else if(timer2.Enabled == false){
                    timer2.Enabled = true;
                    btnStopspeed.Text = "停止滚动";
                }
            }
            /// <summary>
            /// 停止取数
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnStopgetting_Click(object sender, EventArgs e)
            {
                if (timer1.Enabled == true && timer2.Enabled == true) {
                    timer1.Enabled = false;
                    timer2.Enabled = false;
                    btnStopgetting.Text = "取样";
                }
                else if (timer1.Enabled == true && timer2.Enabled == false) {
                    timer1.Enabled = false;
                    timer2.Enabled = false;
                    btnStopgetting.Text = "取样";
                }
                else if (timer1.Enabled == false && timer2.Enabled == true)
                {
                    timer1.Enabled = false;
                    timer2.Enabled = false;
                    btnStopgetting.Text = "取样";
                }
                else if (timer1.Enabled == false && timer2.Enabled == false) {
                    timer1.Enabled = true;
                    timer2.Enabled = true;
                    btnStopgetting.Text = "停止取样";
                }
            }
            /// <summary>
            /// 滚动状态
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void scroll(object sender, EventArgs e)
            {
                if (gdvTrack.DataRowCount.ToString().Length > 0)//如果有数据
                {
                    if (this.gdvTrack.IsLastRow)//如果最后一行
                    {
                        this.gdvTrack.MoveFirst();//滚动到第一行
                    }
                    else
                    {
                        this.gdvTrack.MoveNextPage();//滚动到下一页
                    }
                }
            }
    展开全文
  • Timer详解

    千次阅读 2019-07-31 08:36:50
    文章目录timer介绍:timer的使用:timer源码分析:生产者代码消费者代码timer的schedule和scheduleAtFixedRate区别:timer的缺点:timer的替代产品: timer介绍: Timer是Josh Bloch在jdk1.3发布的一个新的api,...

    timer介绍:

    Timer是Josh Bloch在jdk1.3发布的一个新的api,主要用于做定时任务.

    timer的使用:

    1:schedule(TimerTask task, long delay) 在delay毫秒的延迟后执行task

    2:schedule(TimerTask task, Date time) 在指定的time时间执行task

    3:schedule(TimerTask task, long delay, long period) 在delay毫秒延迟后按照period的周期循环定时执行task

    4:schedule(TimerTask task, Date firstTime, long period)在指定的firstTime时间开始按照period的周期循环定时执行task

    5:scheduleAtFixedRate(TimerTask task, long delay, long period) 这个先理解为和3一样,后面会解释二者的区别

    6:scheduleAtFixedRate(TimerTask task, Date firstTime, long period)这个先理解为和4一样,后面会解释二者的区别

    6的实例:每天24点去执行定时任务

    		Timer timer = new Timer();
            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.HOUR_OF_DAY,24);
            cal.set(Calendar.MINUTE,0);
            cal.set(Calendar.SECOND,0);
            timer.scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {
                    System.out.println("执行任务");
                }
            },cal.getTime(),24*60*60*1000);
    

    timer源码分析:

    TimerThread :单线程/消费者/任务线程
    TaskQueue :任务队列/优先队列/最小平衡堆/容器
    我们写的定时任务是生产者,TimerThread 是消费者,可以看出这是一个单消费者多生产者的模型,而且这个线程还是采取轮询的方式来消费产品,这两个模型决定了Timer的上限。

    	/**
         * timer的任务队列,这个队列共享给TimerThread ,timer.schedule...()生产任务,
         * TimerThread 消费任务,在适合的时候执行该任务,过时了则从队列移除
         */
        private final TaskQueue queue = new TaskQueue();
    	//消费者线程
        private final TimerThread thread = new TimerThread(queue);
    

    下面看生产者的核心方法,所有生产者最终都会走到这个方法

    生产者代码

    private void sched(TimerTask task, long time, long period) {
            if (time < 0)
                throw new IllegalArgumentException("Illegal execution time.");
            //对周期做一下限制 防止溢出
            if (Math.abs(period) > (Long.MAX_VALUE >> 1))
                period >>= 1;
    		
            synchronized(queue) {
                if (!thread.newTasksMayBeScheduled)
                    throw new IllegalStateException("Timer already cancelled.");
    
                synchronized(task.lock) {
                    if (task.state != TimerTask.VIRGIN)
                        throw new IllegalStateException(
                            "Task already scheduled or cancelled");
                    task.nextExecutionTime = time;//这个任务下一次执行时间
                    task.period = period;//执行周期
                    task.state = TimerTask.SCHEDULED;//任务状态
                }
                queue.add(task);//加入最小平衡堆
                if (queue.getMin() == task)//如果堆顶任务就是刚加进去的任务
                    queue.notify();//唤醒堆顶任务
            }
        }
    

    任务状态

    	//This task has not yet been scheduled.
    	//处女,任务还没有被调度,默认是这个
    	static final int VIRGIN = 0;
    	//任务被调度,但是未执行,就是说在队列等待调度
    	static final int SCHEDULED   = 1;
    	//已经执行了,或者正在执行
    	static final int EXECUTED    = 2;
    	//任务被取消with a call to TimerTask.cancel
    	static final int CANCELLED   = 3;
    

    queue.add(task)代码

    	void add(TimerTask task) {
            // 容器初始大小128,以2为指数扩容
            if (size + 1 == queue.length)
                queue = Arrays.copyOf(queue, 2*queue.length);
    		//size初始为0,可以看出queue的下标0被舍弃掉了,直接从下标1开始入堆
    		//这样一来i的左孩子就是2*i了,右孩子是2*i+1.
            queue[++size] = task;
            fixUp(size);//加入堆中后 可能不是最小堆,所以需要对堆做一次fixup调整为最小平衡堆
        }
    

    fixUp(size)代码

     	private void fixUp(int k) {
            while (k > 1) {
                int j = k >> 1;
                if (queue[j].nextExecutionTime <= queue[k].nextExecutionTime)
                    break;
                TimerTask tmp = queue[j];  queue[j] = queue[k]; queue[k] = tmp;
                k = j;
            }
        }
    

    这段代码的意思其实就是把刚刚加入堆的任务安排到合适的地方去。直接将代码不好讲,还是看个实例:没有学过堆的同学建议花两小时学一下,不然可能听不懂。假设某个时刻堆的任务是下图所示,2,3,4这些数字代表nextExecutionTime(下次执行的时间),数字越小说明任务优先级越高。
    2
    / \
    3 4
    某个时刻来了一个nextExecutionTime=1的任务,此时堆中任务如下图所示。
    2(下标1)
    / \
    3 4(下标3)
    /
    1(下标4)
    很明显这已经不是一个最小堆了,我们需要把1往上调整。
    现在来看代码:
    第一次循环
    k=4,j=2
    if(3<=1)break;这里不成立,但是如果来了一个任务的nextExecutionTime>=3 这里会直接break掉,因为已经是最小堆
    交换1和3
    2(下标1)
    / \
    1 4(下标3)
    /
    3(下标4)
    k=2
    第二次循环
    k=2 ,j =1
    if(2<=1)break;这里不成立
    交换1和2
    1(下标1)
    / \
    2 4(下标3)
    /
    3(下标4)
    k=1退出循环,已经是最小堆
    至此生产者的代码就看完了

    消费者代码

    	//单消费者
    	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
                        //这两个时间及其重要 
                        //scheduleAtFixedRate和schedule的区别就体现在这两个时间和+-period上面
                        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 周期任务
                                	//这里的代码及其经典够味
                                	//schedule的period传的是-period
                                	//scheduleAtFixedRate的period是+period
                                	//如果是schedule调度,下一次执行时间改为
                                	// currentTime-task.period(当前时间-(-period))
                                	//这里看出来schedule是依据当前时间来调度的
                                	//如果是scheduleAtFixedRate调度,下一次执行时间是
                                	//executionTime + task.period,
                                	//这里看出来scheduleAtFixedRate是依据执行时间调度的
                                	//(这个执行时间是我们写代码指定的那个时间)							
                                	//并且while(true){}保证scheduleAtFixedRate这种调度方式会自动补上之前缺失的任务。
                                    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) {
                }
            }
        }
    }
    

    queue.removeMin();代码

    	void removeMin() {
            queue[1] = queue[size];//堆顶置为堆尾
            queue[size--] = null;  //堆尾置为null,size--
            fixDown(1);//对堆顶进行一次调整,和fixup反着来,目的都是为了调整成最小堆
        }
    

    timer的schedule和scheduleAtFixedRate区别:

    		Timer timer = new Timer();
            SimpleDateFormat fTime = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            Date date = fTime.parse("2019/7/3 10:50:00");
            timer.scheduleAtFixedRate(new TimerTask(){
                public void run()
                {
                    System.out.println("exec task");
                }
            },date,3*60*1000);
    

    程序指定运行时间是2019/7/3 10:50:00,每隔三分钟运行一次
    如果我等到2019/7/3 10:55:00 去运行这段程序,即已经过了五分钟了。

    使用scheduleAtFixedRate会快速打印两个exec task(第一次2019/7/3 10:50:00,第二次2019/7/3 10:53:00),然后按照2019/7/3 10:56:00–> 2019/7/3 10:59:00这样打印下去。也就是说scheduleAtFixedRate是按照指定的时间开始算,如果程序运行的时间晚于这个指定时间,他会一次性补上之前的任务,然后按照间隔时间去执行。

    如果使用schedule他不会补上之前的任务,而且他是按照实际执行程序的时间开始算,也就是说如果2019/7/3 10:55:00用 去schedule运行这段程序那么下一次打印时间将是2019/7/3 10:58:00.

    timer的缺点:

    缺点一:对于耗时任务及多任务非常不友好

    	Timer timer = new Timer();
    	final long start = System.currentTimeMillis();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    System.out.println("time1:"+ (System.currentTimeMillis()-start));
                    try {
                        //模拟耗时操作
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            },1000);
    
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    System.out.println("time2:"+ (System.currentTimeMillis()-start));
                }
            },2000);
    

    我希望的结果是
    time1:1001
    time2:2001
    可实际上由于单线程的原因结果是
    time1:1001
    time2:4001
    由这个例子看出Timer只适用于耗时短的单任务。

    缺点二:对于运行时异常不友好

    Timer timer = new Timer();
    	final long start = System.currentTimeMillis();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    System.out.println("time1:"+ (System.currentTimeMillis()-start));
                    throw new RuntimeException();
                }
            },1000);
    
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    System.out.println("time2:"+ (System.currentTimeMillis()-start));
                }
            },2000);
    

    在timer1里抛运行时异常会导致time2不可用,这一点问题不大,我们有最佳实践:在run里面手动catch异常进行处理。

    timer的替代产品:

    相比于timer,在jdk1.5的时候,Doug Lea老先生主笔写了juc新api,线程池。其中的带有调度功能的线程池就可以执行定时任务,而且性能及稳定性更优秀。线程池将在下篇博文讲到。

    展开全文
  • java Timer(定时调用、实现固定时间执行)

    万次阅读 多人点赞 2018-01-11 15:59:57
    可以通过java的Timer类来进行定时调用,下面是有关Timer的一些相关知识。 其实就Timer来讲就是一个调度器,而TimerTask呢只是一个实现了run方法的一个类,而具体的TimerTask需要由你自己来实现,例如这样: Timer ...
  • Timer&&TimerTask类

    2019-06-16 13:27:01
    2019独角兽企业重金招聘Python工程师标准>>> ...
  • Timer和TimerTask

    2020-09-06 18:07:49
    其实就Timer来讲就是一个调度器,而TimerTask呢只是一个实现了run方法的一个类,而具体的TimerTask...Timer timer = new Timer(); timer.schedule(new TimerTask() { public void run() { System.out.println("abc")
  • JAVA中使用Timer TimerTask轮循数据库,执行定时任务
  • 《Java源码分析》:Timer/TimerTask

    千次阅读 2016-08-05 22:06:03
    《Java源码分析》:Timer在JDK 5.0之前,java.util.Timer/TimerTask是唯一的内置任务调度方法,而且在很长一段时间里很热衷于使用这种方式进行周期性任务调度。本篇博文就先使用Timer/TimerTask来完成任务的调度。...
  • Java并发编程:Timer和TimerTask  其实就Timer来讲就是一个调度器,而TimerTask呢只是一个实现了run方法的一个类,而具体的TimerTask需要由你自己来实现,例如这样: 1 2 3 4 5 6 ...
  • Java中Timer的用法

    万次阅读 多人点赞 2013-01-14 14:44:48
    timer正好用于此处。 用法很简单,new一个timer,然后写一个timertask的子类即可。 代码如下: package comz.autoupdatefile; import java.util.Timer; import java.util.TimerTask; public class M { ...
  • Timer 用法 matlab

    千次阅读 2012-02-07 20:19:00
    创建定时器对象: ...T = timer('PropertyName1', PropertyValue1, 'PropertyName2', P ropertyValue2,...)[创建一个拥有给定参数的定时器对象] 例子:   t = timer('TimerFcn',@mycallback, 'Pe
  • iOS开发交流群:301058503 ...使用:timer=Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(self.textfieldNotification), userInfo: nil, repeats: true) textfield...
  • Python的定时器

    万次阅读 多人点赞 2016-08-12 20:07:13
    在实际应用中,我们经常需要使用定时器去触发一些事件。Python中通过线程实现定时器timer,其使用非常简单。...')timer = threading.Timer(1, fun_timer)timer.start()输出结果:Hello Timer!Process finished
  • Timers.Timer用法详解

    万次阅读 2018-11-16 10:11:03
    可以应用于WinForm,完全取代WinForm的Timer控件。它们的缺点是不支持直接的拖放,需要手工编码private System.Timers.Timer timer;timer = new System.Timers.Timer(); timer.Interval = 1000;//定时时间 timer...
  • C# Timer用法及实例详解

    万次阅读 2018-04-19 15:06:00
    1.C# Timer用法及实例详解http://developer.51cto.com/art/200909/149829.htmhttp://www.cnblogs.com/OpenCoder/archive/2010/02/23/1672043.html关于C# Timer类 在C#里关于定时器类就有3个C# Timer使用的方法1....
  • timer.schedule —— timer定时器的用法

    万次阅读 2014-10-28 15:34:08
    java.util.Timer定时器,实际上是个线程,定时调度所拥有的TimerTasks。 一个TimerTask实际上就是一个拥有run方法的类,需要定时执行的代码放到run方法体内,TimerTask一般是以匿名类的方式创建。 一个完整的Timer...
  • Timer任务定时器如何终止

    万次阅读 2018-06-18 16:41:53
    Timer类的对象有一个方法可以创建定时任务线程schedule(TimerTask task, long delay)但是自己实际操作后,发现程序运行完毕后,并不能终止这个定时任务线程。需要调用timer对象的cancel()方法才可以终止它。所以,在...
  • 内核定时机制API之timer_setup

    千次阅读 2018-02-14 08:24:33
    timer_setup(timer, callback, flags) 用于为第一次使用timer做好准备,一般和add_timer 配合使用 其使用的例程如下: static void prb_setup_retire_blk_timer(struct packet_sock *po) { struct tpacket_kbdq_...
  • 内核定时器的实现,依赖时钟滴答中断来实现, 实时性比较好   open_softirq(TIMER_SOFTIRQ, run_timer_...add_timer() //将timer 加入内核timer列表中,等待处理   以下为例子源码,仅供参考   #inc...
1 2 3 4 5 ... 20
收藏数 327,148
精华内容 130,859
关键字:

timer