Java多线程详解(十)------ 定时器

1 定时器Timer的使用

Timer类的主要作用就是设置计划任务,但封装任务的类却是TimerTask类。

1.1 schedule(TimerTask task, Date time)

在指定的日期执行一次某一任务。

  1. 执行任务的时间晚于当前时间——在未来执行
public class Test1 {
    public static void main(String[] args) {
        System.out.println("now the time is: " + new Date());
        Calendar calendarRef = Calendar.getInstance();
        calendarRef.add(Calendar.SECOND, 10);
        Date runDate = calendarRef.getTime();
        MyTask myTask = new MyTask();
        Timer timer = new Timer();
        timer.schedule(myTask, runDate);
    }
}

class MyTask extends TimerTask {
    @Override
    public void run() {
        System.out.println("start executing job at " + new Date());
    }
}

上例中任务执行完毕后,进程还未销毁,可以看到编辑器呈红色状态。

public Timer() {
    this("Timer-" + serialNumber());
}
public Timer(String name) {
    thread.setName(name);
    thread.start();
}

创建一个Timer就是启动1个新的线程,那么这个新启动的线程并不是守护线程,一直在运行。

  1. 计划早于当前时间——提前运行,启动时立即执行任务

  2. Timer中允许有多个TimerTask任务

TimerTask是以队列的方式一个一个顺序地执行,所以执行的时间有可能和预期的时间不一致,因为前面的任务有可能消耗的时间较长,则后面的任务运行的时间也被延后。

1.2 schedule(TimerTask task, Date firstTime, long period)

在指定的日期之后按指定的间隔周期,无限循环地执行某一任务。

  1. 计划时间晚于当前时间——在未来执行
  2. 计划时间早于当前时间——提前运行
  3. 任务执行时间被延时——依延时时间定
  4. TimerTask类的cancel()方法:将自身从任务队列中进行清除
  5. Timer类的cancel()方法:将任务队列中全部的任务清空
  6. Timercancel()方法注意事项:有时并不一定会停止计划任务,而是正常执行。原因是Timer类中的cancel()方法有时并没有争抢到queue锁,则让TimerTask类中的任务正常执行。
1.3 schedule(TimerTask task, long delay)

以当前的时间为参考时间,在此时间基础上延迟指定的毫秒数后执行一次TimerTask任务

1.4 schedule(TimerTask task, long delay, long period)

以当前的时间为参考时间,在此时间基础上延迟指定的毫秒数后执行一次TimerTask任务,再以某一间隔时间无限次数地执行某一任务。

1.5 具有追赶特性的scheduleAtFixedRate

方法schedule和方法scheduleAtFixedRate都会按顺序执行,所以不需要考虑非线程安全的问题,两者的主要区别只在于有没有追赶特性。

public class TimerTest9 {
    public static void main(String[] args) {
        MyTask myTask = new MyTask();
        System.out.println("start executing time:" + new Date());
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND) - 20);
        Date runDate = calendar.getTime();
        System.out.println("expect to execute time:" + runDate);
        Timer timer = new Timer();
        timer.schedule(myTask, runDate, 2000);
        // timer.scheduleAtFixedRate(myTask, runDate, 2000);
    }

    static class MyTask extends TimerTask {
        @Override
        public void run() {
            System.out.println("begin timer=" + new Date());
            System.out.println("  end timer=" + new Date());
        }
    }
}
schedule执行结果:
start executing time:Sat Dec 19 15:55:59 CST 2020
expect to execute time:Sat Dec 19 15:55:39 CST 2020
begin timer=Sat Dec 19 15:55:59 CST 2020
  end timer=Sat Dec 19 15:55:59 CST 2020
begin timer=Sat Dec 19 15:56:01 CST 2020
  end timer=Sat Dec 19 15:56:01 CST 2020
begin timer=Sat Dec 19 15:56:03 CST 2020

scheduleAtFixedRate执行结果:
start executing time:Sat Dec 19 16:05:16 CST 2020
expect to execute time:Sat Dec 19 16:04:56 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
  end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
  end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
  end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
  end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
  end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
  end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
  end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
  end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
  end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
  end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
  end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:18 CST 2020
  end timer=Sat Dec 19 16:05:18 CST 2020

追赶特性:将两个时间段内的时间所对应的任务“补充性”地执行。Sat Dec 19 16:04:56 CST 2020 ~ Sat Dec 19 16:05:16 CST 2020

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值