定时器Timer的使用

一.序言:

 在JDK库汇总的Timer类主要负责计划任务的功能,也就是在指定的时间开始执行某一个任务,Timer类的主要左右就是设置计划任务,但封装任务的类却是TimerTask类,执行计划任务的代码要放入TimerTask的子类中,因为TimerTask是一个抽象类.

二.demo演示:

1.指定未来的时间执行任务:

public class MyTask1 extends TimerTask{
        @Override
        public void run() {
            try{
                System.err.println("任务运行了! 时间为: "+new Date());

            }catch (Exception e){
                e.printStackTrace();
            }
        }
    public static void main(String[] args) {
        System.out.println("当前时间为: "+new Date());
        Calendar instance = Calendar.getInstance();
        //对当前时间进行延后10秒,目的是为了测试未来时间
        instance.add(Calendar.SECOND,10);
        //获取到未来10秒后的时间
        Date time = instance.getTime();
        Timer timer = new Timer();
        MyTask1 myTask = new MyTask1();
        timer.schedule(myTask,time);
    }
}

运行结果:
在这里插入图片描述
2.计划时间早于当前时间,则立即执行task任务:

public class MyTask2 extends TimerTask{
    
    @Override
    public void run() {
        System.err.println("执行了,时间为: "+new Date());
    }

    public static void main(String[] args) {
        System.out.println("当前时间为: "+new Date());
        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.SECOND,instance.get(Calendar.SECOND)-10);
        Date time = instance.getTime();
        System.out.println("计划时间为: "+time);
        MyTask2 myTask2 = new MyTask2();
        Timer timer = new Timer();
        timer.schedule(myTask2,time);
    }
}

运行结果:

在这里插入图片描述
3.多个延迟任务执行:

public class MyTask3 {
    public static void main(String[] args) {

        System.out.println("当前时间: "+new Date());
        Date futureTime1 = MyTask3.getFutureTime(10);
        System.out.println("计划时间: "+futureTime1);

        Date futureTime2 = MyTask3.getFutureTime(15);
        System.out.println("计划时间: "+futureTime2);
        TimerTask taskA = new TimerTask() {
            @Override
            public void run() {
                System.out.println("A执行了, 时间为:" + new Date());
            }
        };
        TimerTask taskB = new TimerTask() {
            @Override
            public void run() {
                System.out.println("B执行了, 时间为:" + new Date());
            }
        };

        Timer timer = new Timer();
        timer.schedule(taskA,futureTime1);
        timer.schedule(taskB,futureTime2);

    }

    public static Date getFutureTime(int amount){
        Calendar instance1 = Calendar.getInstance();
        instance1.add(Calendar.SECOND,amount);
        return instance1.getTime();
    }
}

运行结果:
在这里插入图片描述
TimerTask是以队列的方式一个一个被顺序的执行,所以执行的时间有可能与预期的时间不一致,
因为前面的任务有可能消耗的时间较长,则后面的任务运行的时间也被延后.

4.在指定的时间内,有时间间隔的无限期的执行,如果计划时间早于当前时间则立即执行:

public class MyTask4 extends TimerTask{
    @Override
    public void run() {
        System.out.println("执行了,时间为: "+new Date());
    }
    public static void main(String[] args) {
        System.out.println("当前时间为: "+new Date());
        Calendar instance = Calendar.getInstance();
        //计划时间晚于当前时间10秒
//        instance.add(Calendar.SECOND,10);
        //计划时间早于当前时间10秒
        instance.set(Calendar.SECOND,instance.get(Calendar.SECOND)-10);
        Date time = instance.getTime();
        MyTask4 task4 = new MyTask4();
        Timer timer = new Timer();
        timer.schedule(task4,time,4000);
    }
}

运行结果:
在这里插入图片描述
三.Timer类的研究

1.构造方法

 /**
  * this调用的是第三个构造方法
  */
 public Timer() {
     this("Timer-" + serialNumber());
 }

 /**
  * this调用的是第四个构造方法
  * 传入true,表示需要守护进程
  */
 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();
 }

2.核心方法schedule

方法一:

/**
 *  task   待调度的任务
 *  delay 任务执行前的毫秒延迟
 */	
 public void schedule(TimerTask task, long delay) {
	if (delay < 0)
         throw new IllegalArgumentException("Negative delay.");
     sched(task, System.currentTimeMillis()+delay, 0);
}

方法二:

/**
 *    task 待调度的任务
 *    time 执行任务的时间
 */
public void schedule(TimerTask task, Date time) {
        sched(task, time.getTime(), 0);
}

方法三:

/**
 *  task   待调度的任务
 *  delay  任务执行前的毫秒延迟
 *  period 连续任务执行之间的时间(以毫秒为单位)
 */	
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);
}

方法四:

/**
     *  task        待调度的任务
     *  firstTime   第一次任务执行的时间
     *  period      连续任务执行之间的时间(以毫秒为单位)
     */	
public void schedule(TimerTask task, Date firstTime, long period) {
        if (period <= 0)
            throw new IllegalArgumentException("Non-positive period.");
        sched(task, firstTime.getTime(), -period);
    }

最后:
所有的sched()方法调用的都是以下这个方法:

private void sched(TimerTask task, long time, long period) {
        if (time < 0)
            throw new IllegalArgumentException("Illegal execution time.");

        // Constrain value of period sufficiently to prevent numeric
        // overflow while still being effectively infinitely large.
        if (Math.abs(period) > (Long.MAX_VALUE >> 1))
            period >>= 1;

        synchronized(queue) {
            if (!thread.newTasksMayBeScheduled)
                throw new IllegalStateException("Timer already cancelled.");

            synchronized(task.lock) {
                if (task.state != TimerTask.VIRGIN)
                    throw new IllegalStateException(
                        "Task already scheduled or cancelled");
                task.nextExecutionTime = time;
                task.period = period;
                task.state = TimerTask.SCHEDULED;
            }

            queue.add(task);
            if (queue.getMin() == task)
                queue.notify();
        }
    }

以上是个人的学习和理解,希望对大家学习有帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值