种类:
- 接通延时型定时器:接通延时型定时器是各种PLC(可编程控制器)中最常见最基本的定时器,这种定时器在Siemens的PLC中,成为SD型定时器
- 断开延时型定时器:这种定时器是当输入条件00000为ON时无延时作用,只有在输入条件00000为OFF时产生延时作用.在siemens的PLC中,称为SF型定时器
- 保持型接通延时定时器:这种定时器是当输入条件00000为ON后,即产生锁存功能,即使输入条件00000又变为OFF,仍视输入条件位ON,当定时器的当前值等于设定值时,定时器动作,这种定时器在Simens的PLC中,称为SS型定时器
- 脉冲型定时器:这种定时器是当输入条件00000为ON后,定时器即时动作,但经过定时器所设定的时间后,即使输入条件00000仍未ON,定时器却变为OFF状态.即这种定时器ON状态的维持时间是由设定值决定的.如果00000为ON的时续时间小于定时器的设定值,定时器的ON状态维持时间为输入田间00000为ON的持续时间.这种定时器在Siemens的PLC中,称为SP型定时器
- 扩张型脉冲定时器:这种定时器与脉冲型定时器的区别是,最后要输入条件00000出现了ON状态,不管其持续时间多长,均可使定时器为ON的维持的时间与定时器的设定值一致.这种定时器在Siemens的PLC中,称为SE型定时器
在Java中会存在每隔一定时间去执行某个任务的现象,如:每天定时清理服务器上的日志文件,每天定时上传文件或下载文件等。在Java中要实现定时任务,需要使用Timer类
Timer的定义:
有且仅有一个后台线程对多个业务进行定时定频的调度。Timer类可以保证多个线程可以共享单个Timer对象而无需进行外部同步,所以Timer类是线程安全的
核心的两个类:
- java.util.Timer和java.util.TimerTask
- java.util.Timer。实际上是个线程,定时调度所拥有的TimerTasks
- 一个TimerTask实际上就是一个拥有run()方法的类,需要定时执行的代码放到run方法体内,TimerTask一般是以匿名类的方式创建。
- TimerTask类是一个定时任务类,该类实现了Runnable接口,而且是一个抽象类
说明
java.util.TimerTask
TimerTask是一个抽象类,由Timer安排为一次执行或重复执行的任务。
public abstract class TimerTask implements Runnable
它有一个抽象方法run()方法,该方法用于执行相应计时器任务要执行的操作。因此每一个具体的任务类都必须继承TimerTask,然后重写run()方法。
另外它还有两个非抽象的方法:
- boolen cancel(): 取消此计时器任务
- long scheduledExecutionTime(): 返回此任务最近实际执行的安排执行时间。
java.util.Timer
注意:javax.swing包中也有一个Timer类,如果import中用到swing包,要注意名字的冲突。
Timer定时器实例有多种构造方法;
- Timer():创建一个新定时器
- Timer(boolean isDaemon):创建一个新定时器,可以指定其相关的线程作为守护程序运行。
- Timer(String name):创建一个新定时器,其相关的线程具有指定的名称
- Timer(String name,boolean isDaemon):创建一个新计时器,其相关的线程具有指定的名称,并且可以指定作为守护程序运行
Timer定时器的schedule()(调度方法)
下面例子部分参数说明:
delay:延迟执行的毫秒数,即在delay毫秒之后第一次执行
period:重复执行的时间间隔
Timer类有四种使用方法:
/* time为Date类型:在指定时间执行一次。 */
timer.schedule(task, time);
/* firstTime为Date类型,period为long
从firstTime时刻开始,每隔period毫秒执行一次。 */
timer.schedule(task, firstTime, period);
/* delay 为 long类型:从现在起过delay毫秒执行一次 */
timer.schedule(task, delay)
/* delay 为 long, period 为 long:从现在起过delay毫秒以后,每隔 period 毫秒执行一次。*/
timer.schedule(task, delay, period)
**方法名称schedule()和scheduleAtFixedRate()的区别: **
- schedule()方法跟注重保持间隔时间的稳定:保障每隔period时间可调用一次
- scheduleAtFixedRate()方法更注重保持执行频率的稳定:保障多次调用的频率趋近于period时间,如果任务执行时间大于period,会在任务执行之后马上执行下一次任务
scheduleAtFixedRate()
- scheduleAtFixedRate(TimerTask task,Date firstTime,long period):安排指定的任务在指定的时间开始进行重复的固定速率执行。
实例代码说明:
MyTimerTask.java
作为一个需要调度的任务类。
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimerTask;
public class MyTimerTask extends TimerTask {
private String name;
public MyTimerTask(String inputName) {
name = inputName;
}
[@Override]()
public void run() {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("current exec time is:"+ sf.format(calendar.getTime()));
// 重写来自于 TimerTask 的 run()
System.out.println("Current exec name is:" + name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
MyTimer.java
测试调度 MyTimerTask
import java.util.Timer;
public class MyTimer {
public static void main(String[] args) {
// 创建一个 timer 实例
Timer timer = new Timer();
// 创建一个 MyTimerTask 实例
MyTimerTask myTimerTask = new MyTimerTask("No.1");
/* 通过 timer 定时定频调用 myTimerTask的业务逻辑
* 即第一次执行是在当前时间的两秒之后,之后每隔一秒执行一次
*/
timer.schedule(myTimerTask, 2000L, 1000L);
}
}
输入结果:
- current exec time is:2018-06-05 14:35:22
- Current exec name is:No.1
- current exec time is:2018-06-05 14:35:23
- Current exec name is:No.1
- current exec time is:2018-06-05 14:35:24
- Current exec name is:No.1
schedule()的用法
代码紧跟上面的例子来做。
- purge()从定时器任务队列中移除所有已取消的任务
- 应用实例: