Java从入门到放弃(十六)定时器Timer

Timer是java自带的定时器,可以做一些简单的定时任务。

创建对象

        Timer timer = new Timer();
        //定义定时器的名字
        Timer timer1 = new Timer("定时器1");
        //第一个参数:定时器名字,第二参数设置是否是守护线程
        Timer timer2 = new Timer("定时器2", true);

定时器其实就是另起线程执行指定的task,所以这里可以设置是否是守护线程,当主线程挂了,定时器的任务也会结束。

TimerTask

TimerTask是一个实现了Runable的类,代表的是一个定时任务,一个Timer定时器可以有多个定时任务TimerTask同时执行,
TimerTask是一个抽象类,要创建Task任务可以继承TimerTask或者用匿名类创建;

延时任务schedule

  • 1.指定延时时长
        Timer timer = new Timer();

        TimerTask task = new TimerTask(){
            @Override
            public void run() {
                System.out.println(new Date());
            }
        };
        System.out.println(new Date());
        timer.schedule(task,5000);    //5秒钟后执行task任务

输出为:

Sun Jun 10 15:10:31 CST 2018
Sun Jun 10 15:10:36 CST 2018

  • 2.指定时间
        Timer timer = new Timer();

        TimerTask task = new TimerTask(){
            @Override
            public void run() {
                System.out.println(new Date());
            }
        };
        System.out.println(new Date());
          //时间是10秒钟后的时间
        timer.schedule(task,new Date(new Date().getTime()+10000)); 

输出是:

Sun Jun 10 15:29:05 CST 2018
Sun Jun 10 15:29:15 CST 2018

周期任务schedule

        Timer timer = new Timer();

        TimerTask task = new TimerTask(){
            @Override
            public void run() {
                System.out.println(new Date());
            }
        };
        System.out.println(new Date());
        timer.schedule(task,5000,1000);   //5秒后执行,周期是1s

输出是:

Sun Jun 10 15:36:55 CST 2018
Sun Jun 10 15:37:00 CST 2018
Sun Jun 10 15:37:01 CST 2018
Sun Jun 10 15:37:02 CST 2018
Sun Jun 10 15:37:03 CST 2018
Sun Jun 10 15:37:04 CST 2018
Sun Jun 10 15:37:05 CST 2018
…………………

可以看到任务是5秒钟后每过1s打印1次,
和上面的延时任务一样,第二个参数也可以指定时间。

scheduleAtFixedRate和schedule的区别

两者之间的区别在于对于过时时间任务的处理:
schedule:

        Timer timer = new Timer();

        TimerTask task = new TimerTask(){
            @Override
            public void run() {
                System.out.println(new Date());
            }
        };
        System.out.println(new Date());
        //当前时间的5秒钟之前的时间
        timer.schedule(task,new Date(new Date().getTime()-5000),1000);

输出:

Sun Jun 10 15:57:12 CST 2018
Sun Jun 10 15:57:12 CST 2018
Sun Jun 10 15:57:13 CST 2018
Sun Jun 10 15:57:14 CST 2018
Sun Jun 10 15:57:15 CST 2018
………………………………………..

会直接快速输出,并且以当前时间为开始时间进行周期任务
scheduleAtFixedRate:

    Timer timer = new Timer();

        TimerTask task = new TimerTask(){
            @Override
            public void run() {
                System.out.println(new Date());
            }
        };
        System.out.println(new Date());
        timer.scheduleAtFixedRate(task,new Date(new Date().getTime()-5000),1000);

和上面一样的代码,只是调用的方法改成了scheduleAtFixedRate,输出为:

Sun Jun 10 15:59:55 CST 2018
Sun Jun 10 15:59:55 CST 2018
Sun Jun 10 15:59:55 CST 2018
Sun Jun 10 15:59:55 CST 2018
Sun Jun 10 15:59:55 CST 2018
Sun Jun 10 15:59:55 CST 2018
Sun Jun 10 15:59:55 CST 2018
Sun Jun 10 15:59:56 CST 2018
Sun Jun 10 15:59:57 CST 2018
Sun Jun 10 15:59:58 CST 2018
…………………………………..

输出还是以当前时间为起始点,但是会把之前的任务执行完。在追赶上正常的时间前,周期不是指定的周期,而是尽可能快速的把之前发任务执行完。

取消任务

  • 指定取消:
        Timer timer = new Timer();

        TimerTask task1 = new TimerTask(){
            @Override
            public void run() {
                System.out.println("task1:"+new Date());
            }
        };
        TimerTask task2 = new TimerTask(){
            @Override
            public void run() {
                System.out.println("task2:"+new Date());
            }
        };
        System.out.println("start:" + new Date());
        timer.schedule(task1,2000,1000);  //3秒钟后执行,周期为1s
        timer.schedule(task2,3000,1000);
        Thread.sleep(6000);   //主线程暂停6s,再取消task1任务
        System.out.println("取消task1任务");
        task1.cancel();

输出为:

start:Sun Jun 10 16:11:44 CST 2018
task1:Sun Jun 10 16:11:46 CST 2018
task2:Sun Jun 10 16:11:47 CST 2018
task1:Sun Jun 10 16:11:47 CST 2018
task2:Sun Jun 10 16:11:48 CST 2018
task1:Sun Jun 10 16:11:48 CST 2018
task2:Sun Jun 10 16:11:49 CST 2018
task1:Sun Jun 10 16:11:49 CST 2018
取消task1任务
task2:Sun Jun 10 16:11:50 CST 2018
task2:Sun Jun 10 16:11:51 CST 2018
task2:Sun Jun 10 16:11:52 CST 2018
task2:Sun Jun 10 16:11:53 CST 2018
…………………………………………………

可以看到再取消task1后,task1的任务不再执行.
取消全部任务

        Timer timer = new Timer();

        TimerTask task1 = new TimerTask(){
            @Override
            public void run() {
                System.out.println("task1:"+new Date());
            }
        };
        TimerTask task2 = new TimerTask(){
            @Override
            public void run() {
                System.out.println("task2:"+new Date());
            }
        };
        System.out.println("start:" + new Date());
        timer.schedule(task1,2000,1000);
        timer.schedule(task2,3000,1000);
        Thread.sleep(8000);
        System.out.println("取消全部任务");
        timer.cancel();

输出为:

start:Sun Jun 10 16:13:24 CST 2018
task1:Sun Jun 10 16:13:26 CST 2018
task1:Sun Jun 10 16:13:27 CST 2018
task2:Sun Jun 10 16:13:27 CST 2018
task2:Sun Jun 10 16:13:28 CST 2018
task1:Sun Jun 10 16:13:28 CST 2018
task1:Sun Jun 10 16:13:29 CST 2018
task2:Sun Jun 10 16:13:29 CST 2018
task2:Sun Jun 10 16:13:30 CST 2018
task1:Sun Jun 10 16:13:30 CST 2018
task1:Sun Jun 10 16:13:31 CST 2018
task2:Sun Jun 10 16:13:31 CST 2018
取消全部任务

用定时器调用cancel后,定时器内的全部任务都会被取消

守护线程定时器

        Timer timer = new Timer(true);
        TimerTask task1 = new TimerTask(){
            @Override
            public void run() {
                System.out.println("task:"+new Date());
            }
        };
        System.out.println("start:" + new Date());
        timer.schedule(task1,2000,1000);
        Thread.sleep(5000);

输出为:

start:Sun Jun 10 16:19:10 CST 2018
task:Sun Jun 10 16:19:12 CST 2018
task:Sun Jun 10 16:19:13 CST 2018
task:Sun Jun 10 16:19:14 CST 2018

main线程休眠5秒钟后会退出进入dead,所以守护线程定时器也会被强制结束,如果不是守护线程,task会一直执行下去。关于线程方面的可参考入坑JAVA多线程并发(二)线程的生命周期和常用方法

猜你喜欢

转载自blog.csdn.net/qq_34101608/article/details/80642182
今日推荐