先看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() {@Overridepublic void run() {System.out.println("执行了1次");}}, 1000);timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("执行了2次");}}, getDelayTime(2));//第3和第4个task的执行顺序是不确定的,因为时间片的切换导致的微小差别timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("执行了3次");}}, getDelayTime(3), 1000);    //3, -3timer.schedule(new TimerTask() {@Overridepublic void run() {System.err.println("执行了4次");}}, 1000, 1000);}public static void test2(){Timer timer = new Timer();timer.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {System.out.println("AtFixedRate1");}}, getDelayTime(1), 1000);timer.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {System.out.println("AtFixedRate2");}}, 2000, 1000);}public static void test3(){Timer timer = new Timer("isDeamon", true);timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("isDeamon");try {Thread.sleep(10000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}, getDelayTime(2), 2000);}public static void test4(){Timer timer = new Timer("AtFixedRate", false);timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("schedule");}}, getDelayTime(-5), 2000);timer.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {System.out.println("scheduleAtFixedRate");}}, getDelayTime(-5), 2000);}public static void test5(){Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("测试时间为过去时间和将来时间对schedule的影响");}}, getDelayTime(-5));  //立即执行}public static void test6(){//purge: 清洗, 净化Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("测试purge1");}}, getDelayTime(1), 1000);System.out.println("purge: "+timer.purge());timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("测试purge2");}}, getDelayTime(1), 1000);}public static void test7(){//将7和6对比看Timer timer = new Timer();class MyTimerTask extends TimerTask{@Overridepublic 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() {@Overridepublic 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());///}//给定一个时间,返回给定多久以后的Datepublic 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定时器用法详解相关推荐

  1. js 定时器用法详解——setTimeout()、setInterval()、clearTimeout()、clearInterval()

    写在前面: 在js应用中,定时器的作用就是可以设定当到达一个时间来执行一个函数,或者每隔几秒重复执行某段函数.这里面涉及到了三个函数方法:setInterval().setTimeout().clea ...

  2. js定时器用法详解——setTimeout()、setInterval()、clearTimeout()、clearInterval()

    写在前面: 在js应用中,定时器的作用就是可以设定当到达一个时间来执行一个函数,或者每隔几秒重复执行某段函数.这里面涉及到了三个函数方法:setInterval().setTimeout().clea ...

  3. JDK中的Timer和TimerTask详解 目录结构: Timer和TimerTask 一个Timer调度的例子 如何终止Timer线程 关于cancle方式终止线程 反复执行一个任务 sche

    JDK中的Timer和TimerTask详解 目录结构: Timer和TimerTask 一个Timer调度的例子 如何终止Timer线程 关于cancle方式终止线程 反复执行一个任务 schedu ...

  4. python argv 详解_Python3 sys.argv[ ]用法详解

    sys.argv[]说白了就是一个从程序外部获取参数的桥梁,这个"外部"很关键,因为我们从外部取得的参数可以是多个,所以获得的是一个列表(list),也就是说sys.argv其实可 ...

  5. oracle中的exists 和 not exists 用法详解

    from:http://blog.sina.com.cn/s/blog_601d1ce30100cyrb.html oracle中的exists 和 not exists 用法详解 (2009-05- ...

  6. ROW_NUMBER() OVER()函数用法详解 (分组排序 例子多)

    ROW_NUMBER() OVER()函数用法详解 (分组排序 例子多) https://blog.csdn.net/qq_25221835/article/details/82762416 post ...

  7. python的继承用法_【后端开发】python中继承有什么用法?python继承的用法详解

    本篇文章给大家带来的内容是关于python中继承有什么用法?python继承的用法详解,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 面向对象三大特征 1.封装:根据职责将属性和方法 ...

  8. C++中substr()函数用法详解

    C++中substr()函数用法详解 原型: string substr (size_t pos = 0, size_t len = npos) const; 返回一个新构造的string对象,其值初 ...

  9. php theme_path,PHP_Yii2主题(Theme)用法详解,本文实例讲述了Yii2主题(Theme) - phpStudy

    Yii2主题(Theme)用法详解 本文实例讲述了Yii2主题(Theme)用法.分享给大家供大家参考,具体如下: 首先看看主要的配置方式: 'components' => [ 'view' = ...

  10. LayoutInflater的inflate函数用法详解

    LayoutInflater的inflate函数用法详解 LayoutInflater作用是将layout的xml布局文件实例化为View类对象. 获取LayoutInflater的方法有如下三种: ...

最新文章

  1. 蚂蚁金服对研发高要求的领域建模能力是指什么?
  2. Android属性动画 XML
  3. linux内核 mpls,将MPLS编译进linux内核中
  4. re.DOTALL --编写多行模式的正则表达式
  5. 华硕v4000fj笔记本怎么样_所有已开箱笔记本的目录汇总 20200812
  6. linux看请求报文发送的ip,Linux C 实现最简单的ICMP_ECHO请求报文发送
  7. USB2.0协议学习笔记---USB工作过程(类的方法)
  8. 重定向ISA日志到SQL2000
  9. 微信小程序之点餐系统附源码
  10. GAN(生成对抗神经网络)生成MNIST 基于pytorch实现
  11. 实习日记一:jdk的安装和环境变量配置,IDEA和mysql的安装
  12. 对生成对抗网络GANs原理、实现过程、应用场景的理解(附代码),另附:深度学习大神文章列表
  13. 【EI会议征稿】山西财经大学主办!往届全部成功检索!机器学习、大数据与商务智能征稿中!...
  14. matlab plotyy 横坐标,[转载]关于plotyy的坐标轴 设置
  15. 被谢耳朵一直嘲笑的MIT,这次发明了黑镜中的“恐怖机器”
  16. selenium录屏python_Selenium实现录屏的一种方法
  17. 华为路由器:GRE技术
  18. [转载]计算机视觉、机器学习相关领域论文和源代码
  19. 2022-03-30 StackOverflowError与OutOfMemoryError详解
  20. 简单的面向对象思想,写一个传奇人物的属性

热门文章

  1. 张冬:OpenPOWER CAPI为什么这么快?(二)
  2. 青龙自动薅羊毛—【万年历】秒到
  3. 经典Java练习题 Mars Rover
  4. 庆祝下:iOS 开发者企业级计划(299美元/年帐户+邓白氏码免费) 和 Windows Phone公司应用(公司帐户99美元+Symantec企业证书299美元/年))顺利发布成功...
  5. 网络学习 2g 3g 4g 5g技术对比
  6. 自我思考:世界观与方法论——关于做事方法,情商,智商,爱商的深入思索
  7. 17.(cesium之家)cesium调整倾斜摄影位置(高度,平移,旋转,缩放)
  8. UML图详解(九)包图
  9. 阿里云数据工厂DataWorks
  10. stm32f4有重映射么_stm32f4引脚重映射