文章目录

在开发中,我们经常需要一些周期性的操作,例如每隔几分钟就进行某一项操作。这时候我们就要去设置个定时器,Java中最方便、最高效的实现方式是用java.util.Timer工具类,再通过调度java.util.TimerTask任务。

一、基础知识
1. 简介

Timer是一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。实际上是个线程,定时调度所拥有的TimerTasks。
TimerTask是一个抽象类,它的子类由 Timer 安排为一次执行或重复执行的任务。实际上就是一个拥有run方法的类,需要定时执行的代码放到run方法体内。

2. 常用API
//以下是几种常用调度task的方法:   

timer.schedule(task, time);
// time为Date类型:在指定时间执行一次。

timer.schedule(task, firstTime, period);
// firstTime为Date类型,period为long
// 从firstTime时刻开始,每隔period毫秒执行一次。

timer.schedule(task, delay)
// delay 为long类型:从现在起过delay毫秒执行一次

timer.schedule(task, delay, period)
// delay为long,period为long:从现在起过delay毫秒以后,每隔period
// 毫秒执行一次。
二、需求案例
2.1. 案例1
每天定时12:00执行操作,延迟3分钟后再执行

第1步:写一个处理类,使用​​timer.schedule(task, firstTime, period);​​api

package com.gblfy.test;

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;

public class G {
/**
* 每天定时12:00执行操作,延迟3分钟后再执行
*/
public void timer(){
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 12);//控制小时
calendar.set(Calendar.MINUTE, 0);//控制分钟
calendar.set(Calendar.SECOND, 0);//控制秒
Date time = calendar.getTime();//执行任务时间为12:00:00

Timer timer = new Timer();
timer.schedule(new TimerTaskTest2(),60 * 3 * 1000);
}
}

第2步:写一个类​​extends TimerTask​​实现run方法,在方法内部写需要执行的代码

package com.gblfy.test;

import java.util.TimerTask;

public class TimerTaskTest2 extends TimerTask {
@Override
public void run() {
System.out.println("... //每次需要执行的代码放到这里面");
}
}

另一种形式不是输出一句话而是在​​run​​方法内部调用一个自定义方法

package com.gblfy.test;

import java.util.TimerTask;

public class TimerTaskTest2 extends TimerTask {
@Override
public void run() {
System.out.println("... //每次需要执行的代码放到这里面");
Submit();
}

private void Submit() {
System.out.println("-------------自定义方法-------------");
}
}
2.2. 案例2
每天定时12:00执行操作,延迟3分钟后再执行,但是,我需要传参怎样办?

第1步:

package com.gblfy.test;

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;

public class A {
public void timer(String tokenNo) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 12);//控制小时
calendar.set(Calendar.MINUTE, 0);//控制分钟
calendar.set(Calendar.SECOND, 0);//控制秒
Date time = calendar.getTime();//执行任务时间为12:00:00

Timer timer = new Timer();
//每天定时12:00执行操作,延迟3分钟后再执行
// timer.schedule(new TimerTaskTest(tokenNo),time,60 * 3 * 1000);
// timer.schedule(new TimerTaskTest(tokenNo),60 * 3 * 1000);
timer.schedule(new TimerTaskTest(tokenNo), 1 * 1000);
}
public static void main(String[] args) {
A a = new A();
String tokenNo="123";
a.timer(tokenNo);
}
}

第2步:

package com.gblfy.test;

import java.util.TimerTask;

public class TimerTaskTest extends TimerTask {
private String tokenNo;

public TimerTaskTest(String tokenNo) {
this.tokenNo = tokenNo;
}

/**
* 此计时器任务要执行的操作。
*/
@Override
public void run() {
Submit(tokenNo);
System.out.println("-------30分钟之后执行指定时间time执行--------");

}
public void Submit(String tokenNo) {
System.out.println("1111111111"+tokenNo);
}
}
2.3. 案例3
延迟3分钟后再执行,但是,我需要传参怎样办?

只需要烧写一个参数即可

// timer.schedule(new TimerTaskTest(tokenNo),60 * 3 * 1000);

为了方便测试可以写成3秒

.schedule(new TimerTaskTest(tokenNo), 3 * 1000);
三、场景案例
3.1. 在特定时间执行任务,只执行一次
package com.gblfy.test;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TimerTime {
/**
* <p>
* 1.停止timer
* timer.cancel();
* 2.在特定时间执行任务,只执行一次
* public void schedule(TimerTask task,Date time)
* </p>
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
new TimerTime().new Time().start();
}

// 时间格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
// 要执行的时间参数
Date dateTime = new Date("2016/8/13 10:56:00");

// 内部类继承线程 ,创建一个新线程。
class Time extends Thread {
@Override
public void run() {
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
// 重写run方法
@Override
public void run() {
System.out.println("I am a cat");
timer.cancel();
}
}, dateTime);
}
}
}
3.2. 指定第一次执行的时间,然后按照间隔时间,重复执行
package com.gblfy.test;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TimerTime {
/**
* <p>
* 1.停止timer
* timer.cancel();
* 2.在特定时间执行任务,只执行一次
* public void schedule(TimerTask task,Date time)
* </p>
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
new TimerTime().new Time().start();
}

// 时间格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
// 要执行的时间参数
Date dateTime = new Date("2016/8/13 10:56:00");

// 内部类继承线程 ,创建一个新线程。
class Time extends Thread {
@Override
public void run() {
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
// 重写run方法
@Override
public void run() {
System.out.println("I am a cat");
timer.cancel();
}
}, dateTime);
}
}

/**
* 指定第一次执行的时间,然后按照间隔时间,重复执行
* public void schedule(TimerTask task,Date firstTime,long period)
*
* @param task
* @param firstTime
* @param period
*/
public void schedule(TimerTask task, Date firstTime, long period)

// 示例:
// 参照上面的代码,多传一个时间间隔参数,period单位毫秒
class Time2 extends Thread {
@Override
public void run() {
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
// 重写run方法
@Override
public void run() {
System.out.println("I am a cat");
timer.cancel();
}
}, dateTime,1000 * 1);
}
}
}