专栏首页IT笔记分享Java多线程学习(七)——定时器Timer

Java多线程学习(七)——定时器Timer

定时器Timer

在JDK库中,Timer类主要负责计划任务的功能,也就是在指定的时间开始执行某一个任务。

schedule(TimeTask, Date)方法

执行任务的时间晚于当前时间

publicclassMytask{
publicstaticvoid main(String[] args){
System.out.println("当前时间为:"+LocalDateTime.now());
Timer timer = newTimer();
Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 10);
Date date = calendar.getTime();
        timer.schedule(newTimerTask() {
@Override
publicvoid run() {
System.out.println("任务执行了,时间为:"+ LocalDateTime.now());
}
}, date);
}
}
//输出
当前时间为:2019-06-25T07:46:41.911
任务执行了,时间为:2019-06-25T07:46:51.916

可以看到,当任务结束,进程依然处于挂起状态,创建一个Timer就启动一个新的线程,这个新的线程并不是守护线程,一直在运行。

Timer timer = newTimer(true);

将其改为守护进程后发现任务并没有执行直接结束了,这是因为主进程已经结束。

如果任务早于当前时间则立即执行任务。

Timer中允许有多个TimerTask任务运行

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

schedule(TimeTask, Date, long)

该方法作用是指定日期之后按指定的间隔时间,无限的循环执行某一任务。

计划时间晚于当前时间

{
publicstaticvoid main(String[] args){
System.out.println("当前时间为:"+ LocalDateTime.now());
Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 5);
Date date = calendar.getTime();
System.out.println("计划时间为:"+ date);
Timer timer = newTimer();
        timer.schedule(newTimerTask() {
@Override
publicvoid run() {
System.out.println("任务执行了,时间为:"+ LocalDateTime.now());
}
}, date, 4000);
}
}
//输出
当前时间为:2019-06-25T08:02:31.533
计划时间为:TueJun2508:02:36 CST 2019
任务执行了,时间为:2019-06-25T08:02:36.537
任务执行了,时间为:2019-06-25T08:02:40.538
任务执行了,时间为:2019-06-25T08:02:44.539
任务执行了,时间为:2019-06-25T08:02:48.540
任务执行了,时间为:2019-06-25T08:02:52.540
任务执行了,时间为:2019-06-25T08:02:56.540
任务执行了,时间为:2019-06-25T08:03:00.541

可以看到任务每个4秒执行一次并且是无限循环的。

计划时间早于当前时间时候,任务会立即执行直到时间追赶上来为止。

Timertask()的cancel()方法

cancel方法作用是将自己从任务队列中清除。其他任务不受影响。

publicclassMyTask3{
publicstaticvoid main(String[] args){
System.out.println("当前时间为:"+ LocalDateTime.now());
Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 5);
Date date = calendar.getTime();
System.out.println("计划时间为:"+ date);
Timer timer = newTimer();
        timer.schedule(newTimerTask() {
@Override
publicvoid run() {
System.out.println("A run timer = "+ LocalDateTime.now());
this.cancel();
System.out.println("A 将自己cancel了");
}
}, date, 2000);
        timer.schedule(newTimerTask() {
@Override
publicvoid run() {
System.out.println("B run timer = "+ LocalDateTime.now());
}
}, date, 2000);
}
}
// 输出
当前时间为:2019-06-25T08:12:00.516
计划时间为:TueJun2508:12:05 CST 2019
A run timer = 2019-06-25T08:12:05.520
A 将自己cancel了
B run timer = 2019-06-25T08:12:05.520
B run timer = 2019-06-25T08:12:07.521
B run timer = 2019-06-25T08:12:09.521
B run timer = 2019-06-25T08:12:11.522

Timer类的cancel()方法

作用是将任务队列中的全部任务进行清空。

scheduleAtFixedRate与schedule方法

scheduleAtFixedRate方法具有追赶的特性。将两个时间段内的时间所对应的Task任务被“补充性”的执行,这就是Task任务的追赶特性。

publicclassMyTask4{
publicstaticvoid main(String[] args){
System.out.println("现在执行时间:"+ LocalDateTime.now());
Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND)-20);
Date date = calendar.getTime();
System.out.println("计划执行时间:"+ date);
Timer timer = newTimer();
        timer.schedule(newTimerTask() {
@Override
publicvoid run() {
System.out.println("开始:"+LocalDateTime.now());
System.out.println("  结束:"+LocalDateTime.now());
}
}, date, 2000);
}
}
//输出
现在执行时间:2019-06-25T08:25:38.055
计划执行时间:TueJun2508:25:18 CST 2019
开始:2019-06-25T08:25:38.067
结束:2019-06-25T08:25:38.067
开始:2019-06-25T08:25:40.067
结束:2019-06-25T08:25:40.067
开始:2019-06-25T08:25:42.067
结束:2019-06-25T08:25:42.067
开始:2019-06-25T08:25:44.068
结束:2019-06-25T08:25:44.068

时间“08:25:18”到“08:25:38”中所对应的Task都被取消不执行了,这就是Task的不追赶。

publicclassMyTask4{
publicstaticvoid main(String[] args){
System.out.println("现在执行时间:"+ LocalDateTime.now());
Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND)-20);
Date date = calendar.getTime();
System.out.println("计划执行时间:"+ date);
Timer timer = newTimer();
        timer.schedule(newTimerTask() {
@Override
publicvoid run() {
System.out.println("开始:"+LocalDateTime.now());
System.out.println("  结束:"+LocalDateTime.now());
}
}, date, 2000);
}
}
//输出
现在执行时间:2019-06-25T08:25:38.055
计划执行时间:TueJun2508:25:18 CST 2019
开始:2019-06-25T08:25:38.067
结束:2019-06-25T08:25:38.067
开始:2019-06-25T08:25:40.067
结束:2019-06-25T08:25:40.067
开始:2019-06-25T08:25:42.067
结束:2019-06-25T08:25:42.067
开始:2019-06-25T08:25:44.068
结束:2019-06-25T08:25:44.068

scheduleAtFixed会将这段时间内所有的任务都执行一遍。

本文分享自微信公众号 - IT笔记分享(xiaosen_javashare),作者:xiaosen L

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 设计模式(五)——装饰器

    在装饰模式中, 必然有一个最基本、 最核心、 最原始的接口或抽象类充当 Component抽象构件。

    小森啦啦啦
  • 设计模式——工厂模式

    定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法是一个类的实例化延迟到子类。工厂方法可以解耦,降低代码的重复性。

    小森啦啦啦
  • Java多线程学习(三)——synchronized(下)

    用关键字synchronized声明方法是有弊端的。比如线程A调用同步方法执行一个长时间任务,那么线程B就要等较长时间才能调用。

    小森啦啦啦
  • 利用iMacros实现对知网文章的批量下载

    这得感谢HOSTLOC的nop的指点,指点贴见: http://www.hostloc.com/thread-247313-1-1.html

    用户1191760
  • 利用iMacros实现对知网文章的批量下载

    用户1272546
  • 砰砰砰,用你的小拳拳杀出一条血路吧!

    VRPinea
  • Java基于redis实现分布式锁(SpringBoot)

    分布式锁,其实原理是就是多台机器,去争抢一个资源,谁争抢成功,那么谁就持有了这把锁,然后去执行后续的业务逻辑,执行完毕后,把锁释放掉。

    Happyjava
  • 基础知识 | 每日一练(178)

    士人有百折不回之真心,才有万变不穷之妙用。立业建功,事事要从实地着脚,若少慕声闻,便成伪果;讲道修德,念念要从虚处立基,若稍计功效,便落尘情。 ...

    闫小林
  • 10个让程序员瞬间炸毛的奇葩需求(2018最新版)

    Java高级架构
  • 小朋友学C++(1):Hello World!

    在学C++之前,最好先学习一下C语言 让我们先运行一段简单的代码,编译器可以使用 在线C++编译器 或 Xcode(苹果系统) 或Dev C++(Windows...

    海天一树

扫码关注云+社区

领取腾讯云代金券