timer_timertask - CSDN
timer 订阅
人类最早使用的定时工具是沙漏或水漏,但在钟表诞生发展成熟之后,人们开始尝试使用这种全新的计时工具来改进定时器,达到准确控制时间的目的。 展开全文
人类最早使用的定时工具是沙漏或水漏,但在钟表诞生发展成熟之后,人们开始尝试使用这种全新的计时工具来改进定时器,达到准确控制时间的目的。
信息
目    的
准确定位时间
外文名
The timer
早期工具
沙漏或水漏等
种    类
接通延时型定时器等
中文名
定时器
定时器介绍
定时器是通信协议正常运行的基本要素之一,主要用于各种定时和帧重传的任务。通信协议在单片机系统上实现所使用的定时器,定时精度要求不高,但数量要求比较大。由于硬件资源有限,不可能为每一个单独任务分配一个硬件定时器,只能通过单个硬件定时器模拟多个软件定时器的方法,来满足协议中的定时应用需要。 用一定的数据结构将这些软件定时器组织起来,并提供统一的调用接口,称为“定时器管理”。定时器管理主要有2种实现方法:①静态数组法。将定时器节点存储在数组中。优点是逻辑简单,占用ROM较少。但这种方案有明显的缺点:当硬件定时器中断发生时,要对所有定时器节点进行减法操作,时间开销很大,且时延不确定(与定时器数目相关)。②delta链表法。按照定时器的定时值升序排列,形成链表。后一个定时器的定时值是前面所有定时器的值加上本节点的值。这样,在每次的时钟中断处理中,只需对第1个定时器节点进行减法操作,大大减少了时间开销。但是,该方案逻辑复杂,ROM用量大,需要频繁分配回收内存,容易形成内存碎片。
收起全文
  • 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详解

    千次阅读 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,线程池。其中的带有调度功能的线程池就可以执行定时任务,而且性能及稳定性更优秀。线程池将在下篇博文讲到。

    展开全文
  • 四种Timer的区别和用法 1、System.Threading.Timer 线程计时器 1、最底层、轻量级的计时器。基于线程池实现的,工作在辅助线程。 2、它并不是内在线程安全的,并且使用起来比其他计时器更麻烦。此计时器通常不...

    四种Timer的区别和用法

    1、System.Threading.Timer 线程计时器

    1、最底层、轻量级的计时器。基于线程池实现的,工作在辅助线程。

    2、它并不是内在线程安全的,并且使用起来比其他计时器更麻烦。此计时器通常不适合 Windows 窗体环境。

    构造函数:public Timer(TimerCallback callback, object state, int dueTime, int period);

     

    string state=”.”;
    //state参数可以传入想在callback委托中处理的对象。可以传递一个AutoRestEvent,在回调函数中向主函数发送信号。
    Timer timer=new Timer(TimeMethod,state,100,1000)//100表示多久后开始,1000表示隔多久执行一次。
    
    void TimerMethod(object state)
    {Console.Write(state.ToString());}
    
    timer.Dispose();//取消timer执行

     

    2、System.Timers.Timer  服务器计时器

    1、针对服务器的服务程序,基于System.Threading.Timer,被设计并优化成能用于多线程环境。在这种情况下,应该确保事件处理程序不与 UI 交互。在asp.net中一般使用System.Timers.Timer。

    2、继承自Compnent,公开了可以SynchronizingObject 属性,避免了线程池中无法访问主线程中组件的问题(模拟System.Windows.Forms.Timer单线程模式)。但是除非需要对事件的时间安排进行更精确的控制,否则还是应该改为使用 System.Windows.Forms.Timer。

    3、AutoReset属性设置计时器是否在引发Elapsed事件后重新计时,默认为true。如果该属性设为False,则只执行timer_Elapsed方法一次。

    4、System.Timers.Timer是多线程定时器,如果一个Timer没有处理完成,到达下一个时间点,新的Timer同样会被启动。所以,Timer比较适合执行不太耗时的小任务,若在Timer中运行耗时任务,很容易出现由于超时导致的多线程重入问题,即多个线程同时进入timer_Elapsed方法。

     

    System.Timers.Timer timer = new System.Timers.Timer();
    timer.Interval = 500;
    timer.SynchronizingObject = this;
    
    timer.Elapsed+=new System.Timers.ElapsedEventHandler(timer_Elapsed);
    
    timer.Start(); private void timer_Elapsed(Object source, Timers.ElapsedEventArgs e)
    {
        this.tbTimer.Text = value;
    }
    

     

    5、为了应对多线程重入问题。可以加锁,也可以增加标志位。 Interlocked.Exchange提供了一种轻量级的线程安全的给对象赋值的方法,所以使用Interlocked.Exchange给变量赋值。

     

    int inTimer = 0;
            void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
            {
                if (Interlocked.Exchange(ref inTimer, 1) == 0)
                {
                    Thread.Sleep(3000);
                    string currentThreadId = Thread.CurrentThread.ManagedThreadId.ToString();
                    this.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        this.Label_Result.Content += currentThreadId + ",";
                    }), null);
                    Interlocked.Exchange(ref inTimer, 0);
                }
            }

     

    3、System.Windows.Forms.Timer  Windows计时器

    此计时器直接继承自Component,它经过了专门的优化以便与 Windows 窗体一起使用,并且必须在窗口中使用。

    1. Windows计时器建立在基于消息的UI线程上运行,精度限定为5ms。Tick事件中执行的事件与主窗体是同一个线程(单线程),并且对与 UI 交互是安全的。
    2. 只有Enable和Internal两个属性和一个Tick事件,可以使用Start()和Stop()方法控制Enable属性。

     

    using System.Windows.Forms;
    
    public Form1()
    {
        InitializeComponent();
        this.Load += delegate
        {
            Timer timer = new Timer();
            timer.Interval = 500;
            timer.Tick += delegate
            {
                System.Diagnostics.Debug.WriteLine($"Timer Thread: {System.Threading.Thread.CurrentThread.ManagedThreadId}");
                System.Diagnostics.Debug.WriteLine($"Is Thread Pool: {System.Threading.Thread.CurrentThread.IsThreadPoolThread}");
                this.lblTimer.Text = DateTime.Now.ToLongTimeString();
            };
    
            timer.Start();
            System.Diagnostics.Debug.WriteLine($"Main Thread: {System.Threading.Thread.CurrentThread.ManagedThreadId}");
        };
    }

     

    4. System.Windows.Threading.DispatcherTimer

    主要用于WPF中。属性和方法与System.Windows.Forms.Timer类似。DispatcherTimer中Tick事件执行是在主线程中进行的。

    使用DispatcherTimer时有一点需要注意,因为DispatcherTimer的Tick事件是排在Dispatcher队列中的,当系统在高负荷时,不能保证在Interval时间段执行,可能会有轻微的延迟,但是绝对可以保证Tick的执行不会早于Interval设置的时间。如果对Tick执行时间准确性高可以设置DispatcherTimer的priority。

    展开全文
  • Timer用法

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

    2018-04-10 10:26:09
    介绍 ROS 中的时刻、时间间隔、定时器的定义和应用。一、Time1、时刻和间隔ROS 中有 time 和 duration 两种类型,相应的有 ros::Time 和 ros::Duration 类。time 表示的是时刻duration 表示的是时间间隔其统一表示...
  • timer

    2019-06-27 09:27:12
    #region timer 定时器 /// timer ///// /* timer类的作用是设置一个定时器,定时用户指定的函数(当他启动后,他会创建一个新的线程,执行用户指定的方法,),他的传递靠的是 另一个代理对象 TimerCallback 并且...
  • Look ! Timer定时器

    2020-09-17 20:20:45
    schedule(TimerTask task,Date time) 在指定日期执行一次任务 public class MyTask extends TimerTask { @Override public void run() { System.out.println("任务执行了,时间为:"+System.currentTimeMillis())...
  • QTimer

    千次阅读 2019-01-02 11:09:39
    QTimer是一个计时器类  ...QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(update())); timer-&gt;start(1000); this指针对应到类中 其中,SIGNAL(timeou...
  • java Timer(定时调用、实现固定时间执行)

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

    万次阅读 多人点赞 2013-02-28 12:24:16
    其实就Timer来讲就是一个调度器,而TimerTask呢只是一个实现了run方法的一个类,而具体的TimerTask需要由你自己来实现,例如这样: Timer timer = new Timer(); timer.schedule(new TimerTask() { public void run...
  • 继续并发,上篇博客对于ScheduledThreadPoolExecutor没有进行介绍,说过会和Timer一直单独写一篇Blog. 1、Timer管理延时任务的缺陷 a、以前在项目中也经常使用定时器,比如每隔一段时间清理项目中的一些垃圾文件,每...
  • Java中的Timer和TimerTask在Android中的用法

    万次阅读 多人点赞 2012-11-10 11:33:08
    比如UI上的控件需要随着时间改变,我们可以使用Java为我们提供的计时器的工具类,即Timer和TimerTask。  Timer是一个普通的类,其中有几个重要的方法;而TimerTask则是一个抽象类,其中有一个抽象方法run(),...
  • java定时器的使用(Timer

    万次阅读 多人点赞 2008-02-14 13:54:00
    java定时器的使用(Timer)1、在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等。对于这样的操作最方便、高效的实现方式就是使用java.util.Timer工具类。private java.util.Timer timer;timer = ...
  • 关于ets_timer与os_timer

    2019-01-07 19:04:14
    在ESP8266 non_os SDK的 osapi.h 中,做了一些关于ets_timer与os_timer的宏定义,但是需要注意一点这两者并不等价。os_timer_disarm() 等价于ets_timer_disarm(), os_timer_setfn()等价于ets_timer_setfn()。但是...
  • Java进阶(十八)Java实现定时器(Timer)

    万次阅读 2015-11-24 08:13:05
    Java实现定时器(Timer) 绪 在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等。对于这样的操作最方便、高效的实现方式就是使用java.util.Timer工具类。java.util这个包中可以找到Timer和TimerTask...
  • JMeter定时器Timer的使用说明

    万次阅读 2019-03-12 19:33:48
    性能测试方向:后起之秀JMeter与革命前辈Loadrunner的比较,JMeter测试工具的Timer可以根据实际场景设置思考时间,用于等待或是集合点同时并发操作;言归正传,我们来看看JMeter的Timer成员有哪些,及具体作用? 1...
  • 一、Forms.Timer using System.Windows.Forms.Timer; 实现按用户定义的时间间隔引发事件的计时器。此计时器最宜用于 Windows 窗体应用程序中,并且必须在窗口中使用。 这个类在Windows应用程序中使用,用来定期...
  • Timer和TimerTask详解

    万次阅读 多人点赞 2005-01-12 01:38:00
    概览Timer是一种定时器工具,用来在一个后台线程计划执行指定任务。它可以计划执行一个任务一次或反复多次。TimerTask一个抽象类,它的子类代表一个可以被Timer计划的任务。简单的一个例程:import java.util.Timer;...
1 2 3 4 5 ... 20
收藏数 321,665
精华内容 128,666
关键字:

timer