丁岚-timer定时任务

简介: Timer是java.util提供的一个定时器,可以完成一些简单的定时任务,使用TimeTask以及Timer来实现

简介:

TimeTask是要执行的任务,Timer则是调度器

image.png

查看源码则能发现,TimerTask实现的Runnable接口,每次创建一个TimeTask就是创建了一个线程,再使用Timer来启动这个线程,控制这个任务什么时候执行,多久执行一次等。

任务调度

延迟调度

TimerTasktimerTask=newTimerTask() {

  @Override

  publicvoidrun() {

      System.out.println("延迟调度");

 }

};

Timertimer=newTimer();

timer.schedule(timerTask,2000);

这个便是启动后2s,调用TimeTask,延迟时间作为schedule的第二个参数传入进去,单位是毫秒,这个是只会调用一次

TimerTasktimerTask=newTimerTask() {

  @Override

  publicvoidrun() {

      System.out.println(Thread.currentThread().getName()+":"+"延迟多次调度");

 }

};

Timertimer=newTimer();

timer.schedule(timerTask,2000,1000);

而这个是启动后2s调用,之后每1s再次调用,第二个参数未延迟时间,第三个则为每隔多少时间再次调用,单位都是毫秒,这个可以调用多次。

指定时间调度

TimerTasktimerTask=newTimerTask() {

  @Override

  publicvoidrun() {

      System.out.println(Thread.currentThread().getName()+":"+"指定时间调度");

 }

};

Timertimer=newTimer();

longtime=System.currentTimeMillis()+5000;

Datedate=newDate(time);

timer.schedule(timerTask,date);

这个用法和上面延迟调度的用法基本类似,只是第二个参数为调度时间,到了指定的时间自动调度,若时间为过去时间, 则该任务会马上执行,并且不执行之前的任务,这个也是只执行一次,同样,在schedule的第三个参数,也是调用间隔。

TimerTasktimerTask=newTimerTask() {

  @Override

  publicvoidrun() {

      choose++;

      System.out.println(Thread.currentThread().getName()+":"+System.currentTimeMillis()+"延迟多次调度"+choose);

 }

};

Timertimer=newTimer();

longtimeMillis=System.currentTimeMillis()-5000;

timer.scheduleAtFixedRate(timerTask,newDate(timeMillis),1000L);

image.png

image.png

执行调度任可以使用scheduleAtFixedRateschedule两种方法,如果指定的时间为过去时间,那scheduleAtFixedRate则会将之前的任务一起执行,而schedule不会这样,但都是会立即执行。上面的运行结果则是一目了然,前面一张是使用的是scheduleAtFixedRate,在17:38:46运行调用任务时,一次运行了多个,将之前的任务也运行了,而第二张图却没有运行之前的任务。

任务精确性

TimerTasktimerTask=newTimerTask() {

  @Override

  publicvoidrun() {

      try {

          System.out.println("start");

          Thread.sleep(5000L);

          System.out.println(Thread.currentThread().getName()+":"+DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).format(ZonedDateTime.now())+"调度完成");

     } catch (InterruptedExceptione) {

          e.printStackTrace();

     }

 }

};

Timertimer=newTimer();

timer.schedule(timerTask,1000L,2000L);

image.png

从上面的运行结果可以看出,这个时候输出的结果并不是很准确,在上方,我们设置的是2s进行一次调用,但当我们在执行任务的时候,需要的时间超过了2s,那么,频率则不是所设置的时间,这样,就会导致所产生的结果和所预期的结果有误差。

ExecutorServiceexecutorService=Executors.newCachedThreadPool();

TimerTasktimerTask=newTimerTask() {

  @Override

  publicvoidrun() {

      executorService.execute(newRunnable() {

          @Override

          publicvoidrun() {

              try {

                  System.out.println("start"+newDate());

                  Thread.sleep(5000L);

             } catch (InterruptedExceptione) {

                  e.printStackTrace();

             }

         }

     });


 }

};

Timertimer=newTimer();

timer.schedule(timerTask,1000L,2000L);

image.png

这个时候就需要在执行的任务中,在开一个异步线程,这样就避免了,当调度这个任务之后,还需要等待任务完成才能进行下一次调度,从结果中看,这个时候已经是没2s进行一次任务调度,就和所期望的结果是一样的呢。

关闭任务

privatestaticintchoose=0;


publicstaticvoidmain(String[] args) {

      TimerTasktimerTask=newTimerTask() {

          @Override

          publicvoidrun() {

              choose++;

              System.out.println(Thread.currentThread().getName()+":"+"延迟多次调度"+choose);

         }

     };

      Timertimer=newTimer();

      timer.scheduleAtFixedRate(timerTask,2000L,500L);

      stop(timer);

}


publicstaticvoidstop(Timertimer){

  if (choose>8){

      timer.cancel();

 } else {

      try {

          Thread.sleep(1000);

          stop(timer);

     } catch (InterruptedExceptione) {

          e.printStackTrace();

     }

 }

}

当我们在开启调度任务后,可能在某种条件下需要关闭调度任务,就可以使用cancel方法,上面这段代码就是当choose大于八时,关闭调度任务,由于在下面那个递归中使用线程睡眠,可能主线程在睡眠时,调度任务执行了多次,使得choose并不是刚到九时就关闭,这里只是做一个演示。

相关文章
|
11月前
|
Linux Go API
GO的定时器Timer 和定时任务cron
GO的定时器Timer 和定时任务cron
|
Java 测试技术
在多线程中自定义实现定时器(Timer)
在多线程中自定义实现定时器(Timer)
|
Java
(Java)定时器Timer——让你的程序定时执行
(Java)定时器Timer——让你的程序定时执行
129 0
(Java)定时器Timer——让你的程序定时执行
|
消息中间件 Java C#
C# 三个Timer
C# 三个Timer
280 0
C# 三个Timer
|
API 调度 Android开发
【Android 异步操作】Timer 定时器 ( Timer 与 TimerTask 基本使用 | Timer 定时器常用用法 | Timer 源码分析 )
【Android 异步操作】Timer 定时器 ( Timer 与 TimerTask 基本使用 | Timer 定时器常用用法 | Timer 源码分析 )
896 0
|
Java
Java 中Timer和TimerTask 定时器和定时任务使用的例子
<p>转自:<a target="_blank" href="http://blog.csdn.net/kalision/article/details/7692796">http://blog.csdn.net/kalision/article/details/7692796</a></p> <p><span style="font-family:Arial; font-size:14
5030 0
|
Java Spring
定时器Cron配置方法
Quartz Cron表达式主要用于JAVA Spring定时任务中,用法如下: # 每月的最后1天 @Scheduled(cron = "0 0 18 28–31 * ?") public void doAtLastDayOfMonth() { final Calendar calendar = Calendar.
3488 0