目录

  • 1.方法schedule(TimerTask task,Date time)的测试
    • 1.执行任务的时间晚于当前时间:在未来执行的效果
    • 2.计划时间早于当前时间:提前运行的效果
    • 3.多个TimerTask任务及延时的测试
  • 2.方法schedule(TimerTask task,Date firstTime,Long period)的测试
    • 1.计划时间晚于当前时间:在未来执行的效果
    • 2.计划时间早于当前时间:提前运行的效果
    • 3.任务执行时间被延时
    • 4.TimerTask类的cancel()方法
    • 5. Timer 类的 cancel() 方法
    • 6. TImer 的 cancel() 方法注意事项

  定时 / 计划功能在移动开发领域使用较多,比如 Android 技术。定时计划任务功能在 Java 中主要使用的就是 Timer 对象,他在内部使用多线程的方式进行处理,所以它和线程技术还是有非常大的关联的。
  在 JDK 库中 Timer 类主要负责计划任务的功能,也就是在指定的时间开始执行某一个任务。
  Timer 类的主要作用就是设置计划任务,但封装任务的类却是 TimerTask。
  执行计划任务的代码要放入 TimerTask 的子类中,因为 TimerTask 是一个抽象类。

1.方法schedule(TimerTask task,Date time)的测试

  该方法的作用是在指定的日期执行一次某一任务。

1.执行任务的时间晚于当前时间:在未来执行的效果

创建项目5.1.1,创建类Run1.java代码如下:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;public class Run1 {private static Timer timer = new Timer();static public class MyTask extends TimerTask {@Overridepublic void run() {System.out.println("运行了!时间为:" + new Date());}}public static void main(String[] args) {try {MyTask task = new MyTask();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateString = "2020-8-20 11:55:00";Date dateRef = sdf.parse(dateString);System.out.println("字符串时间:" + dateRef.toLocaleString() + "当前时间:" + new Date().toLocaleString());timer.schedule(task, dateRef);} catch (ParseException e) {e.printStackTrace();}}
}

程序运行结果如下所示:

字符串时间:2020-8-20 11:55:00当前时间:2021-8-26 15:59:15
运行了!时间为:Fri Aug 26 15:59:15 CST 2021

任务虽然执行完了,但进程还未销毁,呈红色状态。

创建一个 Timer 就是启动一个新的线程,这个新启动的线程并不是守护线程,所以它一直在运行。

下一步将新创建的Timer改为守护线程。新建java类Run1TimerIsDaemon.java,代码如下:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;public class Run1TimerIsDaemon {private static Timer timer = new Timer(true);static public class MyTask extends TimerTask {@Overridepublic void run() {System.out.println("运行了!时间为:" + new Date());}}public static void main(String[] args) {try {MyTask task = new MyTask();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateString = "2020-8-20 11:55:00";Date dateRef = sdf.parse(dateString);System.out.println("字符串时间:" + dateRef.toLocaleString() + "当前时间:" + new Date().toLocaleString());timer.schedule(task, dateRef);} catch (ParseException e) {e.printStackTrace();}}
}

程序运行结果如下所示:

字符串时间:2020-8-20 11:55:00当前时间:2020-8-26 16:56:35

守护线程创建成功进程退出

  程序运行后迅速结束当前的线程,并且TimerTask中的任务不再被运行,因为进程已经结束了。

2.计划时间早于当前时间:提前运行的效果

  如果执行任务的时间早于当前时间,则立即执行task任务。
示例代码如下:

public static void main(String[] args) {try {MyTask task = new MyTask();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateString = "2020-8-20 11:55:00";Date dateRef = sdf.parse(dateString);System.out.println("字符串时间:" + dateRef.toLocaleString() + "当前时间:" + new Date().toLocaleString());timer.schedule(task, dateRef);} catch (ParseException e) {e.printStackTrace();}}

运行结果如下所示:

字符串时间:2020-8-20 11:55:00当前时间:2021-8-26 17:48:44
运行了!时间为:Fri Aug 26 17:48:44 CST 2021

立即执行task任务

3.多个TimerTask任务及延时的测试

Timer中允许有多个TimerTask任务。
创建类Run2.java,代码如下:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;public class Run2 {private static Timer timer = new Timer();static public class MyTask1 extends TimerTask {@Overridepublic void run() {System.out.println("运行了!时间为:" + new Date());}}static public class MyTask2 extends TimerTask {@Overridepublic void run() {System.out.println("运行了!时间为:" + new Date());}}public static void main(String[] args) {try {MyTask1 task1 = new MyTask1();MyTask2 task2 = new MyTask2();SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateString1 = "2022-8-27 9:00:00";String dateString2 = "2022-8-27 9:01:00";Date dateRef1 = sdf1.parse(dateString1);Date dateRef2 = sdf2.parse(dateString2);System.out.println("字符串1时间:" + dateRef1.toLocaleString() + " 当前时间:" + new Date().toLocaleString());System.out.println("字符串2时间:" + dateRef2.toLocaleString() + " 当前时间:" + new Date().toLocaleString());timer.schedule(task1, dateRef1);timer.schedule(task2, dateRef2);} catch (ParseException e) {e.printStackTrace();}}
}

程序运行结果如下所示:

字符串1时间:2022-8-27 9:00:00 当前时间:2022-8-27 10:45:04
字符串2时间:2022-8-27 9:01:00 当前时间:2022-8-27 10:45:04
运行了!时间为:Sat Aug 27 10:45:04 CST 2022
运行了!时间为:Sat Aug 27 10:45:04 CST 2022

一个Timer中可以运行多个TimerTask任务

  TimerTask 是以队列的方式一个一个被顺序执行的,所以执行的时间有可能和预期的时间不一致,因为前面的任务有可能消耗的时间较长,则后面的任务运行的时间也会被延迟。请看下面的示例。

创建java类Run2Later.java,代码如下:

import org.omg.CORBA.PUBLIC_MEMBER;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;public class Run2Later {private static Timer timer = new Timer();static public class MyTask1 extends TimerTask {@Overridepublic void run() {try {System.out.println("1 begin 运行了!时间为:" + new Date());Thread.sleep(20000);System.out.println("1    end 运行了!时间为:" + new Date());} catch (InterruptedException e) {e.printStackTrace();}}}static public class MyTask2 extends TimerTask {@Overridepublic void run() {System.out.println("2 begin 运行了!时间为:" + new Date());System.out.println("运行了!时间为:" + new Date());System.out.println("2    end 运行了!时间为:" + new Date());}public static void main(String[] args) {try {MyTask1 task1 = new MyTask1();MyTask2 task2 = new MyTask2();SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateString1 = "2022-8-27 11:55:00";String dateString2 = "2022-8-27 11:55:10";Date dateRef1 = sdf1.parse(dateString1);Date dateRef2 = sdf2.parse(dateString2);System.out.println("字符串1时间:" + dateRef1.toLocaleString() + "当前时间:" + new Date().toLocaleString());System.out.println("字符串2时间:" + dateRef2.toLocaleString() + "当前时间:" + new Date().toLocaleString());timer.schedule(task1, dateRef1);timer.schedule(task2, dateRef2);} catch (ParseException e) {e.printStackTrace();}}}
}

程序运行结果如下所示:

字符串1时间:2022-8-27 11:55:00当前时间:2022-8-27 13:59:15
字符串2时间:2022-8-27 11:55:10当前时间:2022-8-27 13:59:15
1 begin 运行了!时间为:Sat Aug 27 13:59:15 CST 2022
1    end 运行了!时间为:Sat Aug 27 13:59:35 CST 2022
2 begin 运行了!时间为:Sat Aug 27 13:59:35 CST 2022
运行了!时间为:Sat Aug 27 13:59:35 CST 2022
2    end 运行了!时间为:Sat Aug 27 13:59:35 CST 2022

任务2的运行时间被延迟

  由于task1需要用时20秒执行完成,task1开始时间是13:59:15,那么将要影响task2的计划任务执行的时间,task2以此时间为基准,向后延迟20秒,task2在13:59:35执行任务。因为Task是被放入队列中的,得一个一个顺序运行。

2.方法schedule(TimerTask task,Date firstTime,Long period)的测试

  该方法的作用是在指定的日期之后,按指定的间隔周期性地无限循环地执行某一任务。

1.计划时间晚于当前时间:在未来执行的效果

创建项目5.1.2,创建类Run.java代码如下:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;public class Run {static public class MyTask extends TimerTask {@Overridepublic void run() {System.out.println("运行了! 时间为: " + new Date());}}public static void main(String[] args) {try {MyTask task = new MyTask();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateString = "2022-08-27 16:20:00";Timer timer = new Timer();Date dateRef = sdf.parse(dateString);System.out.println("字符串时间: " + dateRef.toLocaleString() + "当前时间:" + new Date().toLocaleString());timer.schedule(task, dateRef, 4000);} catch (ParseException e) {e.printStackTrace();}}
}

程序运行结果如下:

字符串时间: 2022-8-27 16:20:00当前时间:2022-8-27 16:19:53
运行了! 时间为: Sat Aug 27 16:20:00 CST 2022
运行了! 时间为: Sat Aug 27 16:20:04 CST 2022
运行了! 时间为: Sat Aug 27 16:20:08 CST 2022
运行了! 时间为: Sat Aug 27 16:20:12 CST 2022
运行了! 时间为: Sat Aug 27 16:20:16 CST 2022
运行了! 时间为: Sat Aug 27 16:20:20 CST 2022
运行了! 时间为: Sat Aug 27 16:20:24 CST 2022
运行了! 时间为: Sat Aug 27 16:20:28 CST 2022
运行了! 时间为: Sat Aug 27 16:20:32 CST 2022
运行了! 时间为: Sat Aug 27 16:20:36 CST 2022

从运行结果来看,每隔4运行一次 TimerTask 任务,并且是无限期地重复执行。

2.计划时间早于当前时间:提前运行的效果

如果计划时间早于当前时间,则立即执行 task 任务。
示例代码如下:

   public static void main(String[] args) {try {MyTask task = new MyTask();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateString = "2022-08-27 16:20:00";Timer timer = new Timer();Date dateRef = sdf.parse(dateString);System.out.println("字符串时间: " + dateRef.toLocaleString() + "当前时间:" + new Date().toLocaleString());timer.schedule(task, dateRef, 4000);} catch (ParseException e) {e.printStackTrace();}}

程序运行结果如下所示:

字符串时间: 2022-8-27 16:20:00当前时间:2022-8-27 16:31:39
运行了! 时间为: Sat Aug 27 16:31:39 CST 2022
运行了! 时间为: Sat Aug 27 16:31:43 CST 2022
运行了! 时间为: Sat Aug 27 16:31:47 CST 2022
运行了! 时间为: Sat Aug 27 16:31:51 CST 2022
运行了! 时间为: Sat Aug 27 16:31:55 CST 2022
运行了! 时间为: Sat Aug 27 16:31:59 CST 2022

立即执行task任务

控制台打印的结果是,程序运行后立即执行task任务。

3.任务执行时间被延时

创建Run2_1.java代码如下:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;public class Run2_1 {static public class MyTaaskA extends TimerTask {@Overridepublic void run() {try {System.out.println("A运行了! 时间为: " + new Date());Thread.sleep(5000);System.out.println("A结束了! 时间为: " + new Date());} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {try {MyTaaskA taaskA = new MyTaaskA();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateString = "2022-08-29 9:55:00";Timer timer = new Timer();Date dateRef = sdf.parse(dateString);System.out.println("字符串时间: " + dateRef.toLocaleString() + "当前时间:" + new Date().toLocaleString());timer.schedule(taaskA, dateRef, 4000);} catch (ParseException e) {e.printStackTrace();}}
}

程序运行结果如下所示:

字符串时间: 2022-8-28 9:55:00当前时间:2022-8-28 9:54:53
A运行了! 时间为: Mon Aug 28 09:55:00 CST 2022
A结束了! 时间为: Mon Aug 28 09:55:05 CST 2022
A运行了! 时间为: Mon Aug 28 09:55:05 CST 2022
A结束了! 时间为: Mon Aug 28 09:55:10 CST 2022
A运行了! 时间为: Mon Aug 28 09:55:10 CST 2022
A结束了! 时间为: Mon Aug 28 09:55:15 CST 2022
A运行了! 时间为: Mon Aug 28 09:55:15 CST 2022
A结束了! 时间为: Mon Aug 28 09:55:20 CST 2022
A运行了! 时间为: Mon Aug 28 09:55:20 CST 2022

4.TimerTask类的cancel()方法

  TimerTask类中的cancel()方法的作用是将自身从任务队列中清除。
创建项目Run2.java文件,代码如下:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;public class Run2 {static public class MyTaskA extends TimerTask {@Overridepublic void run() {System.out.println("A运行了! 时间为: " + new Date());this.cancel();}}static public class MyTaskB extends TimerTask {@Overridepublic void run() {System.out.println("B运行了! 时间为: " + new Date());}}public static void main(String[] args) {try {MyTaskA taskA = new MyTaskA();MyTaskB taskB = new MyTaskB();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateString = "2022-08-27 9:00:00";Timer timer = new Timer();Date dateRef = sdf.parse(dateString);System.out.println("字符串时间: " + dateRef.toLocaleString() + "当前时间:" + new Date().toLocaleString());timer.schedule(taskA, dateRef, 4000);timer.schedule(taskB, dateRef, 4000);} catch (ParseException e) {e.printStackTrace();}}
}

程序运行后的效果如下所示:

字符串时间: 2022-8-27 9:00:00当前时间:2022-8-28 10:41:13
A运行了! 时间为: Mon Aug 28 10:41:13 CST 2022
B运行了! 时间为: Mon Aug 28 10:41:13 CST 2022
B运行了! 时间为: Mon Aug 28 10:41:17 CST 2022
B运行了! 时间为: Mon Aug 28 10:41:21 CST 2022
B运行了! 时间为: Mon Aug 28 10:41:25 CST 2022
B运行了! 时间为: Mon Aug 28 10:41:29 CST 2022

TimerTaskA仅运行一次后被清除了

  TimerTask 类的 cancel() 放啊是将子什么从任务队列中被移除,其他任务不受影响。

5. Timer 类的 cancel() 方法

  和 TimerTask 类中的 cancel() 方法清除自身不同,Timer 类中的 cancel() 方法的作用是将任务队列中的全部任务清空。
创建项目Run3.java文件,代码如下:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;public class Run3 {private static Timer timer = new Timer();static public class MyTaskA extends TimerTask {@Overridepublic void run() {System.out.println("A运行了! 时间为: " + new Date());timer.cancel();}}static public class MyTaskB extends TimerTask {@Overridepublic void run() {System.out.println("B运行了! 时间为: " + new Date());}}public static void main(String[] args) {try {MyTaskA taskA = new MyTaskA();MyTaskB taskB = new MyTaskB();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateString = "2022-08-27 11:00:00";Date dateRef = sdf.parse(dateString);System.out.println("字符串时间: " + dateRef.toLocaleString() + "当前时间:" + new Date().toLocaleString());timer.schedule(taskA, dateRef, 4000);timer.schedule(taskB, dateRef, 4000);} catch (ParseException e) {e.printStackTrace();}}
}

程序运行结果如下所示:

字符串时间: 2022-8-27 11:00:00当前时间:2022-9-3 16:03:23
A运行了! 时间为: Sat Sep 03 16:03:23 CST 2022

进程被清空

  全部任务被清除,并且进程被销毁,按钮由红色变成灰色。

6. TImer 的 cancel() 方法注意事项

  Timer 类中的 cancel() 方法有时并不一定会停止执行任务之花,而是正常执行。
创建项目Run4.java文件,代码如下:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;public class Run4 {static int i = 0;static public class MyTask extends TimerTask {@Overridepublic void run() {System.out.println("正常执行了" + i);}}public static void main(String[] args) {while (true) {try {i++;Timer timer = new Timer();MyTask task = new MyTask();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateString = "2022-08-27 11:00:00";Date dateRef = sdf.parse(dateString);timer.schedule(task, dateRef);timer.cancel();} catch (ParseException e) {e.printStackTrace();}}}
}

程序运行后结果如下所示:

正常执行了8
正常执行了59
正常执行了71
正常执行了151
正常执行了162
正常执行了343
正常执行了495
正常执行了516
正常执行了563
正常执行了761
正常执行了1091
正常执行了1227
正常执行了1250
正常执行了1283
正常执行了1651

并没有停止执行

  这是因为 Timer 类中的 cancel() 方法有时并没有争抢到 queue 锁,所以 TimerTask 类中的任务继续正常执行。

以上代码下载请点击该链接:https://github.com/Yarrow052/Java-package.git

定时器Timer(一)—— 定时器Timer的使用相关推荐

  1. java wait定时_java定时器的使用(Timer)

    java定时器的使用(Timer) 1.在应用开发中,常常须要一些周期性的操作,比方每5分钟运行某一操作等. 对于这种操作最方便.高效的实现方式就是使用java.util.Timer工具类. priv ...

  2. python timer使用-Python timer定时器两种常用方法解析

    这篇文章主要介绍了Python timer定时器两种常用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 方法一,使用线程中现成的: 这种一般 ...

  3. Matlab练习:timer(定时器)

    前言 某位同学毕设需要时间精确同步,因此,拜托我写一个定时产生信号的程序,要学就学扎实,因此顺便就把matlab 里面timer的文档给看了一遍. 正文 一下是help timer的内容,将对此进行分 ...

  4. 如何在ViewModel中正确地使用Timer(定时器)

    内容摘要: 这是我在某个客户那边讲课的时候遇到一个小问题,在ViewModel中创建的一个Timer,并不会被自动停止,即便使用该ViewModel的View已经被关闭了.这个问题的原因在于Timer ...

  5. 记录js定时器产生 Deferred long-running timer task(s) to improve scrolling smoothness

    前言 某日,在前台js中有一个倒计时发短信的需求,一次发送后,间隔60s才能继续发送,在页面调试的时候发现出现 Deferred long-running timer task(s) to impro ...

  6. java 定时器10秒_Java定时器的使用(Timer)

    java定时器的使用(Timer) 1.在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等.对于这样的操作最方便.高效的实现方式就是使用java.util.Timer工具类. priv ...

  7. Apollo 笔记(03)— Cyber RT Python 接口(channel 读和写、server/client 通信、record 文件读写信息查询、timer 时间定时器操作)

    https://cyber-rt.readthedocs.io/en/latest/CyberRT_Python_API.html https://cyber-rt.readthedocs.io/en ...

  8. Linux时间子系统之高分辨率定时器层(HR Timer)

    在前面介绍定时器层的文章中我们已经知道了在Linux内核中已经存在了一个管理定时器的通用框架.不过它也有很多不足,最大的问题是其精度不是很高.哪怕底层的定时事件设备精度再高,定时器层的分辨率只能达到T ...

  9. MC9S12G128 Timer (定时器溢出中断 延迟函数)

    MC9S12G128 Timer (定时器溢出中断 延迟函数) 溢出中断 延迟函数 寄存器 溢出中断 void TIM_Init(void) {TSCR1_TEN = 1; TSCR1_TFFCA = ...

  10. java定时器的使用(Timer)

    1.在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等. 对于这样的操作最方便.高效的实现方式就是使用java.util.Timer工具类. private java.util.Tim ...

最新文章

  1. idea 搭建spring boot 项目
  2. 使用commons-dbutils
  3. 「AI」我喜欢的几个人工智能方面的头条号
  4. 【异常】Error: ERROR 1012 (42M03): Table undefined. (state=42M03,code=1012)
  5. ActiveMQ(一)简介与架构
  6. eclipse中的感叹号和x号解决方法
  7. IIS Express 使用详细说明
  8. windows服务编写原理(上)
  9. 20164301 Exp3 免杀原理与实践
  10. 如何防止IDEA 每次启动javaWEB项目都自动打开浏览器标签页
  11. Django 基础,创建一个Django,并成功在网页中运行
  12. clock()函数的使用
  13. Confluence wiki上传文件时报“不能上传文件至Confluence中,服务器可能已失效”
  14. 判别模型、生成模型和朴素贝叶斯模型
  15. 【分享】豆瓣上排名top100的书籍
  16. FITC标记亲和纯化大鼠抗小鼠IgG(H+L)二抗说明书
  17. 使用outlook 2007配置microsoft exchange邮箱方法步骤
  18. 秋招实习季,教你制作在线简历
  19. Excel数据分析之数组
  20. 利用SPSS做数据分析②之数据处理2

热门文章

  1. JS获取网页大小和鼠标当前坐标
  2. 如意人生守护·典藏版:论赔付力度,这款产品是碾压级的!
  3. JKD+Tomcat+Eclipse基础配置
  4. T3备份提示原先格式化该文件时所用扇区大小为512
  5. scrapy html页面加载未完成,Scrapy与scrapy-splash框架快速加载js页面
  6. linux 列转行函数,Linux 文本行列转换
  7. 百度AI 2020年的这份成绩单,让我们看到AI全面进入生活的清晰图景
  8. “第一股”争夺战:每日优鲜、叮咚买菜及美菜网谁能杀出重围?
  9. PTA - 数据库合集16
  10. 使用c语言实现传输的流量控制