java之定时器Timer
文章目录
- 1 概览
- 2 终止Timer线程
- 3 反复执行一个任务
- 4 进一步分析schedule和scheduleAtFixedRate
- 5 一些注意的问题
1 概览
Timer
是一种定时器工具,用来在一个后台线程计划执行指定任务。它可以计划执行一个任务一次或反复多次。
TimerTask
一个抽象类,它的子类代表一个可以被Timer
计划的任务。
简单的一个例程:
import java.util.Timer;
import java.util.TimerTask;
/**
* Simple demo that uses java.util.
* Timer to schedule a task to execute
* once 5 seconds have passed.
*/
public class Reminder { Timer timer; public Reminder(int seconds) { timer = new Timer(); timer.schedule(new RemindTask(), seconds*1000); }
class RemindTask extends TimerTask { public void run() { System.out.println("Time's up!"); timer.cancel(); //Terminate the timer thread } } public static void main(String args[]) { System.out.println("About to schedule task."); new Reminder(5); System.out.println("Task scheduled."); }}
运行结果:
About to schedule task.
5秒钟之后你会看到:
Time's up!
这个小例子可以说明一些用Timer
线程实现和计划执行一个任务的基础步骤:
实现自定义的TimerTask
的子类,run
方法包含要执行的任务代码,在这个例子里,这个子类就是RemindTask
实例化Timer
类,创建计时器后台线程。
实例化任务对象 (new RemindTask())
,制定执行计划。
这里用schedule
方法,第一个参数是TimerTask
对象,第二个参数表示开始执行前的延时时间(单位是milliseconds
,这里定义了5000
)。
还有一种方法可以指定任务的执行时间,如下例,指定任务在11:01 p.m
执行:
//Get the Date corresponding to 11:01:00 pm today.Calendar calendar =Calendar.getInstance();calendar.set(Calendar.HOUR_OF_DAY,23);calendar.set(Calendar.MINUTE, 1);calendar.set(Calendar.SECOND, 0);Date time = calendar.getTime();timer = new Timer();timer.schedule(new RemindTask(), time);
2 终止Timer线程
默认情况下,只要一个程序的timer
线程在运行,那么这个程序就会保持运行。当然,可以通过以下四种方法终止一个timer
线程:
- timer.cancle()方法
调用timer
的cancle
方法。可以从程序的任何地方调用此方法,甚至在一个timer task
的run
方法里 - 成为daemon线程
让timer
线程成为一个daemon
线程(可以在创建timer
时使用new Timer(true)
达到这个目地),这样当程序只有daemon
线程的时候,它就会自动终止运行。 - 删除timer对象引用
当timer
相关的所有task
执行完毕以后,删除所有此timer
对象的引用(置成null
),这样timer
线程也会终止 - System.exit方法
调用System.exit
方法,使整个程序(所有线程)终止。
Reminder
的例子使用了第一种方式。在这里不能使用第二种方式,因为这里需要程序保持运行直到timer
的任务执行完成,如果设置成daemon
,那么当main
线程结束的时候,程序只剩下timer
这个daemon
线程,于是程序不会等timer
线程执行task
就终止了。
有些时候,程序的终止与否并不只与timer
线程有关。举个例子,如果我们使用AWT
来beep
,那么AWT
会自动创建一个非daemon
线程来保持程序的运行。下面的代码我们对Reminder
做了修改,加入了beeping
功能,于是我们需要加入System.exit
的调用来终止程序。
import java.util.Timer;
import java.util.TimerTask;
import java.awt.Toolkit;/**
* Simple demo that uses java.util.Timer to schedule a task to execute
* once 5 seconds have passed.
*/public class ReminderBeep {Toolkit toolkit;Timer timer;public ReminderBeep(int seconds) {toolkit = Toolkit.getDefaultToolkit();timer = new Timer();timer.schedule(new RemindTask(), seconds*1000);}class RemindTask extends TimerTask {public void run() {System.out.println("Time's up!");toolkit.beep();//timer.cancel(); //Not necessary because we call System.exitSystem.exit(0); //Stops the AWT thread (and everything else)}}public static void main(String args[]) {System.out.println("About to schedule task.");new ReminderBeep(5);System.out.println("Task scheduled.");}
}
3 反复执行一个任务
先看一个例子:
public class AnnoyingBeep {Toolkit toolkit;Timer timer;public AnnoyingBeep() {toolkit = Toolkit.getDefaultToolkit();timer = new Timer();timer.schedule(new RemindTask(),0, //initial delay1*1000); //subsequent rate}class RemindTask extends TimerTask {int numWarningBeeps = 3;public void run() {if (numWarningBeeps > 0) {toolkit.beep();System.out.println("Beep!");numWarningBeeps--;} else {toolkit.beep();System.out.println("Time's up!");//timer.cancel(); //Not necessary because we call System.exitSystem.exit(0); //Stops the AWT thread (and everything else)}}}...
}执行,你会看到如下输出:Task scheduled.
Beep!
Beep! //one second after the first beep
Beep! //one second after the second beep
Time's up! //one second after the third beep
这里使用了三个参数的schedule
方法用来指定task
每隔一秒执行一次。
如下所列为所有Time
r类用来制定计划反复执行task
的方法 :
schedule(TimerTask task, long delay, long period)
schedule(TimerTask task, Date time, long period)
scheduleAtFixedRate(TimerTask task, long delay, long period)
scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
当计划反复执行的任务时,如果注重任务执行的平滑度,那么请使用schedule
方法,如果你在乎的是任务的执行频度那么使用 scheduleAtFixedRate
方法。 例如,这里使用了schedule
方法,这就意味着所有beep
之间的时间间隔至少为1
秒,也就是说,如果有一个beap
因为某种原因迟到了(未按计划执行),那么余下的所有beep
都要延时执行。如果想让这个程序正好在3
秒以后终止,无论哪一个beep
因为什么原因被延时,那么需要使用scheduleAtFixedRate
方法,这样当第一个beep
迟到时,那么后面的beep
就会以最快的速度紧密执行(最大限度的压缩间隔时间)
4 进一步分析schedule和scheduleAtFixedRate
2
个参数的schedule
在制定任务计划时, 如果指定的计划执行时间scheduledExecutionTime<=systemCurrentTime
,则task
会被立即执行。scheduledExecutionTime
不会因为某一个task
的过度执行而改变。
3
个参数的schedule
在制定反复执行一个task
的计划时,每一次执行这个task
的计划执行时间随着前一次的实际执行时间而变,也就是scheduledExecutionTime
(第n+1
次)=realExecutionTime
(第n
次)+periodTime
。
也就是说如果第n
次执行task
时,由于某种原因这次执行时间过长,执行完后的systemCurrentTime
>=scheduledExecutionTime
(第n+1
次),则此时不做时隔等待,立即执行第n+1
次task
,而接下来的第n+2
次task
的scheduledExecutionTime
(第n+2
次)就随着变成了realExecutionTime
(第n+1
次)+periodTime
。说白了,这个方法更注重保持间隔时间的稳定。
3
个参数的scheduleAtFixedRate
在制定反复执行一个task
的计划时,每一次执行这个task
的计划执行时间在最初就被定下来了,也就是 scheduledExecutionTime
(第n次)=firstExecuteTime+n*periodTime
;如果第n
次执行task
时,由 于某种原因这次执行时间过长,执行完后的systemCurrentTime>=scheduledExecutionTime
(第n+1
次),则 此时不做period
间隔等待,立即执行第n+1
次task
,而接下来的第n+2
次的task
的scheduledExecutionTime
(第n+2
次)依然还是firstExecuteTime+(n+2)*periodTime
这在第一次执行task
就定下来了。说白了,这个方法更注重保持执行频率的稳定。
5 一些注意的问题
每一个Timer
仅对应唯一一个线程
Timer
不保证任务执行的十分精确
Timer
类的线程安全的
java之定时器Timer相关推荐
- Java的定时器Timer和定时任务TimerTask应用以及原理简析
记录:272 场景:Java JDK自带的定时器Timer和定时任务TimerTask应用以及原理简析.在JDK工具包:java.util中可以找到源码,即java.util.Timer和java.u ...
- java捕获定时器抛出的异常_详细了解Java中定时器Timer的使用及缺陷分析
在需要定时并且周期执行任务时,在最初的JAVA工具类库中,Timer可以实现任务的定时周期执行的需求,不过有一定的缺陷,比如,Timer是基于绝对时间而非相对时间,因此Timer对系统时钟比较敏感,本 ...
- java之定时器任务Timer用法
在项目开发中,经常会遇到需要实现一些定时操作的任务,写过很多遍了,然而每次写的时候,总是会对一些细节有所遗忘,后来想想可能是没有总结的缘故,所以今天小编就打算总结一下可能会被遗忘的小点: 1. pub ...
- Java定时器Timer
Java定时器Timer 在JDK库中,Timer类主要负责计划任务的功能,也就是在指定的时开始执行某一个任务.Timer类的主要作用就是设置计划任务,但封装任务的类却是TimerTask类,执行计划 ...
- Java定时器Timer学习之一
2019独角兽企业重金招聘Python工程师标准>>> 种类: 接通延时型定时器:接通延时型定时器是各种PLC(可编程控制器)中最常见最基本的定时器,这种定时器在Siemens的PL ...
- java定时器阻塞主线程_Java基础_死锁、线程组、定时器Timer
一.死锁问题: 死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放.由于线程被无限期地阻塞,因此程序不可能正常终止. 比如,线程一需要第一把所,此时锁处于空闲状态,给了 ...
- Java定时器Timer和第三方定时器Quartz
概述 定时器在应用广泛,比如定时统计数据生成报表.每隔设定的时间提醒用户等.Java.util包自带的定时器Timer提供简单的定点执行功能,而Quartz是一个第三方提供的定时器框架. 对比 Tim ...
- java定时器关闭再重启_Android定时器Timer的停止和重启实现代码
本文介绍了Android定时器Timer的停止和重启实现代码,分享给大家,具体如下: 7月份做了一个项目,利用自定义控件呈现一幅动画,当时使用定时器来控制时间,但是当停止开启时总是出现问题.一直在寻找 ...
- java定时器timer_Java定时器Timer
Java定时器Timer 在JDK库中,Timer类主要负责计划任务的功能,也就是在指定的时开始执行某一个任务.Timer类的主要作用就是设置计划任务,但封装任务的类却是TimerTask类,执行计划 ...
最新文章
- 华为js面试题_四面腾讯与华为,大厂前端面试真BT!
- cmder默认的命令提示符λ改成$
- ThinkPHP导入第三方类库Vendor
- 01 MySQL锁概述
- 2021-05-25 传递函数阶跃响应指标的matlab计算
- JVM调优系列:(二)JVM运行时数据区域
- dtree 无法出现横向滚动条 (clip)
- (转载)用oracle触发器对记录表增加记录的问题
- 由于不能随便改路径,所以写在这里
- Dynamipsgui入门教程
- Windows互斥锁的使用
- 为什么每个邮件收到后都会有一个htm的附件_Python3.x 发送各种形式的告警邮件内容...
- Java 递归算法解决“八皇后问题”
- win2012服务器 注册表,第十一章 Windows Server 2012 R2 注册表域注册表编辑器 ---学习笔记...
- 『前端面试资料』 前端面试考题汇总 摘自校内某内推群群公告
- 用SDK包开发K66FX18学习笔记(4)
- 第二十三章 Unity 材质
- c语言less函数,Less 函数
- Spring Boot 入门系列(二十八) JPA 的实体映射关系,一对一,一对多,多对多关系映射!...
- python复利计算_python复利代码