简单的例子
package com.fang;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
* @author 川川
* @version 1.0
* @description: TODO
* @date 2022/1/16 13:53
*/
public class TimerTaskTest {
public static void main(String[] args) {
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("TimerTask当前之间为:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
}
};
Timer timer = new Timer();
long delay = 0;
long period = 1000;
timer.schedule(timerTask, delay, period);
}
}
运行结果:
TimerTask原理
TimerTask就是一个实现了的Runnable接口且提供了一个抽象方法run()的抽象类
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package java.util;
/**
* A task that can be scheduled for one-time or repeated execution by a Timer.
*
* @author Josh Bloch
* @see Timer
* @since 1.3
*/
public abstract class TimerTask implements Runnable {
/**
* This object is used to control access to the TimerTask internals.
*/
final Object lock = new Object();
/**
* The state of this task, chosen from the constants below.
*/
int state = VIRGIN;
/**
* This task has not yet been scheduled.
*/
static final int VIRGIN = 0;
/**
* This task is scheduled for execution. If it is a non-repeating task,
* it has not yet been executed.
*/
static final int SCHEDULED = 1;
/**
* This non-repeating task has already executed (or is currently
* executing) and has not been cancelled.
*/
static final int EXECUTED = 2;
/**
* This task has been cancelled (with a call to TimerTask.cancel).
*/
static final int CANCELLED = 3;
/**
* Next execution time for this task in the format returned by
* System.currentTimeMillis, assuming this task is scheduled for execution.
* For repeating tasks, this field is updated prior to each task execution.
*/
long nextExecutionTime;
/**
* Period in milliseconds for repeating tasks. A positive value indicates
* fixed-rate execution. A negative value indicates fixed-delay execution.
* A value of 0 indicates a non-repeating task.
*/
long period = 0;
/**
* Creates a new timer task.
*/
protected TimerTask() {
}
/**
* The action to be performed by this timer task.
*/
public abstract void run();
/**
* Cancels this timer task. If the task has been scheduled for one-time
* execution and has not yet run, or has not yet been scheduled, it will
* never run. If the task has been scheduled for repeated execution, it
* will never run again. (If the task is running when this call occurs,
* the task will run to completion, but will never run again.)
*
* <p>Note that calling this method from within the <tt>run</tt> method of
* a repeating timer task absolutely guarantees that the timer task will
* not run again.
*
* <p>This method may be called repeatedly; the second and subsequent
* calls have no effect.
*
* @return true if this task is scheduled for one-time execution and has
* not yet run, or this task is scheduled for repeated execution.
* Returns false if the task was scheduled for one-time execution
* and has already run, or if the task was never scheduled, or if
* the task was already cancelled. (Loosely speaking, this method
* returns <tt>true</tt> if it prevents one or more scheduled
* executions from taking place.)
*/
public boolean cancel() {
synchronized(lock) {
boolean result = (state == SCHEDULED);
state = CANCELLED;
return result;
}
}
/**
* Returns the <i>scheduled</i> execution time of the most recent
* <i>actual</i> execution of this task. (If this method is invoked
* while task execution is in progress, the return value is the scheduled
* execution time of the ongoing task execution.)
*
* <p>This method is typically invoked from within a task's run method, to
* determine whether the current execution of the task is sufficiently
* timely to warrant performing the scheduled activity:
* <pre>{@code
* public void run() {
* if (System.currentTimeMillis() - scheduledExecutionTime() >=
* MAX_TARDINESS)
* return; // Too late; skip this execution.
* // Perform the task
* }
* }</pre>
* This method is typically <i>not</i> used in conjunction with
* <i>fixed-delay execution</i> repeating tasks, as their scheduled
* execution times are allowed to drift over time, and so are not terribly
* significant.
*
* @return the time at which the most recent execution of this task was
* scheduled to occur, in the format returned by Date.getTime().
* The return value is undefined if the task has yet to commence
* its first execution.
* @see Date#getTime()
*/
public long scheduledExecutionTime() {
synchronized(lock) {
return (period < 0 ? nextExecutionTime + period
: nextExecutionTime - period);
}
}
}
Timer原理
Timer构造函数
它一共有4个构造函数
- 无参构造函数: 通过Timer为前缀构造一个线程
/**
* Creates a new timer. The associated thread does <i>not</i>
* {@linkplain Thread#setDaemon run as a daemon}.
*/
public Timer() {
this("Timer-" + serialNumber());
}
- 第二个构造函数:传入了是否为守护线程,如果是,主线程结束后会自动结束,不需要调用cancel。
public Timer(boolean isDaemon) {
this("Timer-" + serialNumber(), isDaemon);
}
- 第三个构造函数:传入并设置线程的名字,然后启动
public Timer(String name) {
thread.setName(name);
thread.start();
}
- 第四个构造函数:可以设置线程名字以及是否是守护线程,并且启动。
public Timer(String name, boolean isDaemon) {
thread.setName(name);
thread.setDaemon(isDaemon);
thread.start();
}
Timer方法
Timer提供了6个调度方法
- 安排指定任务在指定延迟后执行
public void schedule(TimerTask task, long delay) {
if (delay < 0)
throw new IllegalArgumentException("Negative delay.");
sched(task, System.currentTimeMillis()+delay, 0);
}
- 安排指定任务在指定时间执行,如果时间是过去,则安排任务立即执行
public void schedule(TimerTask task, Date time) {
sched(task, time.getTime(), 0);
}
- 安排指定的任务重复固定时间间隔执行,且在指定的延迟后开始
public void schedule(TimerTask task, long delay, long period) {
if (delay < 0)
throw new IllegalArgumentException("Negative delay.");
if (period <= 0)
throw new IllegalArgumentException("Non-positive period.");
sched(task, System.currentTimeMillis()+delay, -period);
}
- 从指定时间开始,以重复的固定时间间隔执行安排指定的任务
public void schedule(TimerTask task, Date firstTime, long period) {
if (period <= 0)
throw new IllegalArgumentException("Non-positive period.");
sched(task, firstTime.getTime(), -period);
}
- 安排指定任务以重复固定速率执行,在指定延迟后开始
public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
if (delay < 0)
throw new IllegalArgumentException("Negative delay.");
if (period <= 0)
throw new IllegalArgumentException("Non-positive period.");
sched(task, System.currentTimeMillis()+delay, period);
}
- 从指定时间开始,安排指定任务以重复固定速率执行
public void scheduleAtFixedRate(TimerTask task, Date firstTime,
long period) {
if (period <= 0)
throw new IllegalArgumentException("Non-positive period.");
sched(task, firstTime.getTime(), period);
}
Timer属性
TaskQueue:此类表示一个定时器任务队列
TimerThread: 这个帮助类实现了定时器的任务执行线程,它等待定时器队列上的任务,在它们触发时执行它们,宠幸安排重复的任务,并从队列中移除取消的任务和花费的非重复任务。
Timer总结
- TimerTask时调度任务的具体内容
- TaskQueue存放要执行的TimerTask,下标越小优先级最高
- TimerThread是Thread的扩展类,从TaksQueue中获取下标为1的TimerTask执行,并根据是否是重复任务对TaskQueue进行处理
- Timer主要就是配置任务执行时间,间隔,执行内容,TimerThread和TaskQueue位于Timer类中。
需要注意的是:如果要用TimerTask,一定要记得使用try catch,如果遇到不能捕获的异常Timer就终止了