一, 简介
在 java 的 jdk 中提供了 Timer,TimerTask 两个类来做定时任务.
Timer 是一种定时器工具, 用来在一个后台线程计划执行指定任务, 而 TimerTask 一个抽象类, 它的子类代表一个可以被 Timer 计划的任务.
---------------------
Timer 类
在工具类 Timer 中, 提供了四个构造方法, 每个构造方法都启动了计时器线程, 同时 Timer 类可以保证多个线程可以共享单个 Timer 对象而无需进行外部同步, 所以 Timer 类是线程安全的. 但是由于每一个 Timer 对象对应的是单个后台线程, 用于顺序执行所有的计时器任务, 一般情况下我们的线程任务执行所消耗的时间应该非常短, 但是由于特殊情况导致某个定时器任务执行的时间太长, 那么他就会 "独占" 计时器的任务执行线程, 其后的所有线程都必须等待它执行完, 这就会延迟后续任务的执行, 使这些任务堆积在一起, 具体情况我们后面分析.
当程序初始化完成 Timer 后, 定时任务就会按照我们设定的时间去执行, Timer 提供了 schedule 方法, 该方法有多中重载方式来适应不同的情况, 如下:
schedule(TimerTask task, Date time): 安排在指定的时间执行指定的任务.
schedule(TimerTask task, Date firstTime, long period) : 安排指定的任务在指定的时间开始进行重复的固定延迟执行.
schedule(TimerTask task, long delay) : 安排在指定延迟后执行指定的任务.
schedule(TimerTask task, long delay, long period) : 安排指定的任务从指定的延迟后开始进行重复的固定延迟执行.
同时也重载了 scheduleAtFixedRate 方法, scheduleAtFixedRate 方法与 schedule 相同, 只不过他们的侧重点不同, 区别后面分析.
scheduleAtFixedRate(TimerTask task, Date firstTime, long period): 安排指定的任务在指定的时间开始进行重复的固定速率执行.
scheduleAtFixedRate(TimerTask task, long delay, long period): 安排指定的任务在指定的延迟后开始进行重复的固定速率执行.
TimerTask
TimerTask 类是一个抽象类, 由 Timer 安排为一次执行或重复执行的任务. 它有一个抽象方法 run() 方法, 该方法用于执行相应计时器任务要执行的操作. 因此每一个具体的任务类都必须继承 TimerTask, 然后重写 run() 方法.
另外它还有两个非抽象的方法:
boolean cancel(): 取消此计时器任务.
long scheduledExecutionTime(): 返回此任务最近实际执行的安排执行时间.
二, 实例
2.1, 指定延迟时间执行定时任务
- public class TimerTest01 {
- Timer timer;
- public TimerTest01(int time){
- timer = new Timer();
- timer.schedule(new TimerTaskTest01(), time * 1000);
- }
- public static void main(String[] args) {
- System.out.println("timer begin....");
- new TimerTest01(3);
- }
- }
- public class TimerTaskTest01 extends TimerTask{
- public void run() {
- System.out.println("Time's up!!!!");
- }
- }
运行结果:
首先打印: timer begin....
3 秒后打印: Time's up!!!!
2.2, 在指定时间执行定时任务
- public class TimerTest02 {
- Timer timer;
- public TimerTest02(){
- Date time = getTime();
- System.out.println("指定时间 time=" + time);
- timer = new Timer();
- timer.schedule(new TimerTaskTest02(), time);
- }
- public Date getTime(){
- Calendar calendar = Calendar.getInstance();
- calendar.set(Calendar.HOUR_OF_DAY, 11);
- calendar.set(Calendar.MINUTE, 39);
- calendar.set(Calendar.SECOND, 00);
- Date time = calendar.getTime();
- return time;
- }
- public static void main(String[] args) {
- new TimerTest02();
- }
- }
- public class TimerTaskTest02 extends TimerTask{
- @Override
- public void run() {
- System.out.println("指定时间执行线程任务...");
- }
- }
当时间到达 11:39:00 时就会执行该线程任务, 当然大于该时间也会执行!! 执行结果为:
指定时间 time=Tue Jun 10 11:39:00 CST 2014
指定时间执行线程任务...
如果大于该时间不想要执行的解决办法:
- public class SandTimer {
- public void timerRun() {
- // 一天的毫秒数
- long daySpan = 24 * 60 * 60 * 1000;
- // 规定的每天时间 09:16:00 运行
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 09:16:00");
- // 首次运行时间
- try {
- Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(sdf.format(new Date()));
- // 如果今天的已经过了 首次运行时间就改为明天
- if (System.currentTimeMillis()> startTime.getTime()){
- startTime = new Date(startTime.getTime() + daySpan);
- }
- Timer t = new Timer();
- TimerTask task = new TimerTask() {
- @Override
- public void run() {
- System.out.print("定时器执行");
- }
- };
- // 以每 24 小时执行一次
- t.schedule(task, startTime, daySpan);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- public static void main(String[] args) {
- new SandTimer().timerRun();
- }
- ---------------------
- public class TimerTest03 {
- Timer timer;
- public TimerTest03(){
- timer = new Timer();
- timer.schedule(new TimerTaskTest03(), 1000, 2000);
- }
- public static void main(String[] args) {
- new TimerTest03();
- }
- }
- public class TimerTaskTest03 extends TimerTask{
- @Override
- public void run() {
- Date date = new Date(this.scheduledExecutionTime());
- System.out.println("本次执行该线程的时间为:" + date);
- }
- }
- public class TimerTest04 {
- private Timer timer;
- public long start;
- public TimerTest04(){
- this.timer = new Timer();
- start = System.currentTimeMillis();
- }
- public void timerOne(){
- timer.schedule(new TimerTask() {
- public void run() {
- System.out.println("timerOne invoked ,the time:" + (System.currentTimeMillis() - start));
- try {
- Thread.sleep(4000); // 线程休眠 4000
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }, 1000);
- }
- public void timerTwo(){
- timer.schedule(new TimerTask() {
- public void run() {
- System.out.println("timerTwo invoked ,the time:" + (System.currentTimeMillis() - start));
- }
- }, 3000);
- }
- public static void main(String[] args) throws Exception {
- TimerTest04 test = new TimerTest04();
- test.timerOne();
- test.timerTwo();
- }
- }
- timerOne invoked ,the time:1001
- timerOne invoked ,the time:3001
- timerOne invoked ,the time:1000
- timerTwo invoked ,the time:5001
- public class TimerTest04 {
- private Timer timer;
- public TimerTest04(){
- this.timer = new Timer();
- }
- public void timerOne(){
- timer.schedule(new TimerTask() {
- public void run() {
- throw new RuntimeException(); // 抛出异常
- }
- }, 1000);
- }
- public void timerTwo(){
- timer.schedule(new TimerTask() {
- public void run() {
- System.out.println("我会不会执行呢??");
- }
- }, 1000);
- }
- public static void main(String[] args) {
- TimerTest04 test = new TimerTest04();
- test.timerOne();
- test.timerTwo();
- }
- }
- public class ScheduledExecutorTest {
- private ScheduledExecutorService scheduExec;
- public long start;
- ScheduledExecutorTest(){
- this.scheduExec = Executors.newScheduledThreadPool(2);
- this.start = System.currentTimeMillis();
- }
- public void timerOne(){
- scheduExec.schedule(new Runnable() {
- public void run() {
- System.out.println("timerOne,the time:" + (System.currentTimeMillis() - start));
- try {
- Thread.sleep(4000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- },1000,TimeUnit.MILLISECONDS);
- }
- public void timerTwo(){
- scheduExec.schedule(new Runnable() {
- public void run() {
- System.out.println("timerTwo,the time:" + (System.currentTimeMillis() - start));
- }
- },2000,TimeUnit.MILLISECONDS);
- }
- public static void main(String[] args) {
- ScheduledExecutorTest test = new ScheduledExecutorTest();
- test.timerOne();
- test.timerTwo();
- }
- }
- public class ScheduledExecutorTest {
- private ScheduledExecutorService scheduExec;
- public long start;
- ScheduledExecutorTest(){
- this.scheduExec = Executors.newScheduledThreadPool(2);
- this.start = System.currentTimeMillis();
- }
- public void timerOne(){
- scheduExec.schedule(new Runnable() {
- public void run() {
- throw new RuntimeException();
- }
- },1000,TimeUnit.MILLISECONDS);
- }
- public void timerTwo(){
- scheduExec.scheduleAtFixedRate(new Runnable() {
- public void run() {
- System.out.println("timerTwo invoked .....");
- }
- },2000,500,TimeUnit.MILLISECONDS);
- }
- public static void main(String[] args) {
- ScheduledExecutorTest test = new ScheduledExecutorTest();
- test.timerOne();
- test.timerTwo();
- }
- }
来源: http://www.bubuko.com/infodetail-2932006.html