Timer使用

Posted 雪山上的蒲公英

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Timer使用相关的知识,希望对你有一定的参考价值。

1. Timer简介

Timer是jdk中提供的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次。

    

通过创建Timer对象,然后调用Timer的schedule方法,将TimerTask实例作为参数,从而实现定时调度TimerTask(其中TimerTask对象要继承TimerTask对象,复写run方法)。

Timer工具类

    

2.Timer函数的使用

2.1 Timer定时函数 

看参数应该很好理解

    

结合demo进行展示(第四个方法)

step1:new一个TimerTask的子类,重写run方法来指定具体的任务

package com.zang.timer;

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;
    }
    //重写run方法,打印当前时间。
    @Override
    public void run() {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //打印当前文件的内容
        System.out.println("Current exec name is " + sdf.format(calendar.getTime()));
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }    
}

step2:new一个Timer类,Timer的构造函数里会起一个单独的线程来执行计划任务。

package com.zang.timer;

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

public class MyTimer {

    public static void main(String[] args) {
        //1.创建一个Timer实例
        Timer timer = new Timer();
        //2.创建一个MyTimerTask实例
        MyTimerTask myTimerTask = new MyTimerTask("My First Timer...");
        
        //日期格式化和输出当前时间
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("current time is " + sdf.format(calendar.getTime()));
        
        //3.通过timer定时定频率调用MyTimerTask的业务逻辑
        //两秒之后第一次执行,之后每隔一秒执行一次
        timer.schedule(myTimerTask, 2000L, 1000L);
    }
}

jdk中的代码实现如下:

public Timer() {
     this("Timer-" + serialNumber());
}

public Timer(String name) {
     thread.setName(name);
     thread.start();
}

输出如下:

2.2 Timer其他函数(此处不作详解)

TimerTask的cancel()函数的作用:取消当前TimerTask里的任务。

TimerTask的scheduleExecutionTime()作用:返回此任务最近实际执行的已安排执行的时间,返回值:最近发生此任务执行安排的时间,为long型。

Timer对象的cancel()函数的作用:终止此计时器,丢弃所有当前已安排的任务。

Timer的purge()函数的作用:从此计时器的任务队列中移除所有已取消的任务。返回值:从队列中移除的任务数。

 2.3 schedule 和 scheduleAtFixedRate的区别

这两个方法都是任务调度方法,他们之间区别是,schedule会保证任务的间隔是按照定义的period参数严格执行的,如果某一次调度时间比较长,那么后面的时间会顺延保证调度间隔都是period,而scheduleAtFixedRate是严格按照调度时间来的,如果某次调度时间太长了,那么会通过缩短间隔的方式保证下一次调度在预定时间执行。举个栗子:你每个3秒调度一次,那么正常就是0,3,6,9s这样的时间,如果第二次调度花了2s的时间,如果是schedule,就会变成0,3+2,8,11这样的时间,保证间隔,而scheduleAtFixedRate就会变成0,3+2,6,9,压缩间隔,保证调度时间。即schedule的执行基于上一次的完成时间,  scheduleAtFixedRate的执行基于上一次的开始时间。

3. 综合使用demo

利用Timer控制两个机器人——灌水机器人负责灌水,水满即停止工作;跳舞机器人不负责灌水,水满之后跳舞两秒,停止工作。

创建两个TimerTask的子类,重写run方法来指定具体的任务。

package com.zang.timer;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimerTask;

public class DancingRobot extends TimerTask{

    @Override
    public void run() {
        //获取最近一次任务执行时间,并将其格式化
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Schedule exec name is " + sdf.format(scheduledExecutionTime()));
        System.out.println("I am dacing.... ");
    }
}
package com.zang.timer;

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

public class WaterRobot extends TimerTask {

    private Timer timer;
    //水桶的容量,最大容量为5L
    private Integer bucketCapacity = 0;
    
    public WaterRobot(Timer inputTimer) {
        timer = inputTimer;
    }

    @Override
    public void run() {
        //注水直到水满为止
        if(bucketCapacity < 5){
            System.out.println("Add 1L water into the bucket.");
            bucketCapacity++;
        }else{
            //水满之后停止
            System.out.println("The number of canceled task in timer is(BEFORE) " + timer.purge());
            cancel();
            System.out.println("The bucket is fulling and the waterRobot has been aborted.");
            System.out.println("Current water is "+ bucketCapacity +"L");
            //输出被取消的任务数
            System.out.println("The number of canceled task in timer is(AFTER) " + timer.purge());
            //等待两秒,终止timer里的所有内容
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            timer.cancel();
        }       
    }
}

Timer对象执行任务

package com.zang.timer;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;

public class RobotExecutor {

    public static void main(String[] args) {
        Timer timer = new Timer();
        //获取当前时间
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current time is " + sdf.format(calendar.getTime()));
        
        DancingRobot dr = new DancingRobot();
        WaterRobot wr = new WaterRobot(timer);
        
        /*
         * 灌水机器人负责灌水,水满即停止工作
         * 跳舞机器人不负责灌水,水满之后跳舞两秒,停止工作
         */
        timer.schedule(dr, calendar.getTime(), 2000);
        timer.schedule(wr, calendar.getTime(), 1000);
    }
}

控制台输出:

 

以上是关于Timer使用的主要内容,如果未能解决你的问题,请参考以下文章

delphi中的timer 控件代码问题

JAVA随笔篇一(Timer源代码分析和scheduleAtFixedRate的使用)

vb中timer怎么用

Erlang timer:sleep(1000) 导致线程死机

c#出现timer线程跑丢的情况,网上有说明需要线程重启来解决问题,请提供举例代码。

Private Sub Timer1_Timer()这段代码的意思?