Java定时器Timer简述

概述

主要用于Java线程里指定时间或周期运行任务。Timer是线程安全的,但不提供实时性(real-time)保证。

构造函数

Timer()

默认构造函数。

Timer(boolean)

指定关联线程是否作为daemon线程。

Timer(String)

指定关联线程的名称。

Timer(String, boolean)

同时指定关联线程的名称和是否作为daemon。

schdule方法

schedule(TimerTask task, long delay)

以当前时间为基准,延迟指定的毫秒后执行一次TimerTask任务。

schedule(TimerTask task, Date time)

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

如果日期time早于当前时间,则立刻执行。

使用示例

public class Demo {
 private static Timer timer = new Timer();
 public static class MyTask extends TimerTask {
 @Override
 public void run() {
  System.out.println("Run Time:" + new Date().toString());
 }
 }
 public static void main(String[] args) {
 try {
  MyTask task = new MyTask();
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  String dateStr = "2016-12-27 14:36:00";
  Date date = sdf.parse(dateStr);
  System.out.println("Date = " + date.toString() + " NowTime = " + new Date().toString());
  timer.schedule(task, date);
 } catch (ParseException e) {
  e.printStackTrace();
 }
 }
}

执行结果

Date = Tue Dec 27 14:36:00 CST 2016 NowTime = Tue Dec 27 21:28:04 CST 2016
Run Time:Tue Dec 27 21:28:04 CST 2016

说明是立刻执行。

schedule(TimerTask task, long delay, long period)

以当前时间为基准,延迟指定的毫秒后,再按指定的时间间隔地无限次数的执行TimerTask任务。(fixed-delay execution)

使用示例

public class Demo {
 private static Timer timer = new Timer();
 public static class MyTask extends TimerTask {
 @Override
 public void run() {
  System.out.println("Run Time: " + new Date().toString());
 }
 }
 public static void main(String[] args) {
 MyTask task = new MyTask();
 System.out.println("Now Time: " + new Date().toString());
 timer.schedule(task, 3000, 5000);
 }
}

执行结果

Now Time: Tue Dec 27 21:34:59 CST 2016
Run Time: Tue Dec 27 21:35:02 CST 2016
Run Time: Tue Dec 27 21:35:07 CST 2016
Run Time: Tue Dec 27 21:35:12 CST 2016
Run Time: Tue Dec 27 21:35:17 CST 2016

说明以当前基准时间延迟3秒后执行一次,以后按指定间隔时间5秒无限次数的执行。

schedule(TimerTask task, Date firstTime, long period)

在指定的日期之后,按指定的时间间隔地无限次数的执行TimerTask任务。(fixed-delay execution)

如果日期firstTime早于当前时间,则立刻执行,且不执行在时间差内的任务。

使用示例

public class Demo {
 private static Timer timer = new Timer();
 public static class MyTask extends TimerTask {
 @Override
 public void run() {
  System.out.println("Run Time:" + new Date().toString());
 }
 public static void main(String[] args) {
  try {
  MyTask task = new MyTask();
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  String dateStr = "2016-12-27 14:36:00";
  Date date = sdf.parse(dateStr);
  System.out.println("Date = " + date.toString() + " NowTime = " + new Date().toString());
  timer.schedule(task, date, 3000);
  } catch (ParseException e) {
  e.printStackTrace();
  }
 }
 }
}

执行结果

Date = Tue Dec 27 14:36:00 CST 2016 NowTime = Tue Dec 27 21:43:30 CST 2016
Run Time:Tue Dec 27 21:43:30 CST 2016
Run Time:Tue Dec 27 21:43:33 CST 2016
Run Time:Tue Dec 27 21:43:36 CST 2016

说明指定的之间早于当前时间,则立刻执行,不会补充时间差内的任务

scheduleAtFixedRate方法

scheduleAtFixedRate(TimerTask task, long delay, long period)

以当前时间为基准,延迟指定的毫秒后,再按指定的时间间隔周期性地无限次数的执行TimerTask任务。(fixed-rate execution)

使用示例

public class Demo {
 private static Timer timer = new Timer();
 public static class MyTask extends TimerTask {
 @Override
 public void run() {
  System.out.println("Run Time: " + new Date().toString());
 }
 }
 public static void main(String[] args) {
 MyTask task = new MyTask();
 System.out.println("Now Time: " + new Date().toString());
 timer.scheduleAtFixedRate(task, 3000, 5000);
 }
}

执行结果

Now Time: Tue Dec 27 21:58:03 CST 2016
Run Time: Tue Dec 27 21:58:06 CST 2016
Run Time: Tue Dec 27 21:58:11 CST 2016
Run Time: Tue Dec 27 21:58:16 CST 2016
Run Time: Tue Dec 27 21:58:21 CST 2016

说明以当前基准时间延迟3秒后执行一次,以后按指定间隔时间5秒无限次数的执行。

scheduleAtFixedRate(TimerTask task, Date firstTime, long period)

在指定的日期之后,按指定的时间间隔周期性地无限次数的执行TimerTask任务。(fixed-rate execution)

如果日期firstTime早于当前时间,则立即执行,并补充性的执行在时间差内的任务。

使用示例

public class Demo {
 private static Timer timer = new Timer();
 public static class MyTask extends TimerTask {
 @Override
 public void run() {
  System.out.println("Run Time:" + new Date().toString());
 }
 public static void main(String[] args) {
  try {
  MyTask task = new MyTask();
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  String dateStr = "2016-12-27 22:02:00";
  Date date = sdf.parse(dateStr);
  System.out.println("Date = " + date.toString() + " NowTime = " + new Date().toString());
  timer.scheduleAtFixedRate(task, date, 5000);
  } catch (ParseException e) {
  e.printStackTrace();
  }
 }
 }
}

执行结果

Date = Tue Dec 27 22:02:00 CST 2016 NowTime = Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:55 CST 2016
Run Time:Tue Dec 27 22:03:00 CST 2016
Run Time:Tue Dec 27 22:03:05 CST 2016

说明指定的之间早于当前时间,则立刻执行。

在时间22:02:00--22:02:54内大约有11个5秒间隔,则优先补充性的执行在时间差内的任务,然后在22:02:55补充完毕(执行12次。ps:0-55秒区间段内首位都算上,正好触发12次),此后每隔5秒执行一次定时任务。

执行任务延时对比之 schedule 和 scheduleAtFixedRate

schedule不延时

使用示例

public class Demo {
 private static Timer timer = new Timer();
 private static int runCount = 0;
 public static class MyTask extends TimerTask {
 @Override
 public void run() {
  try {
  System.out.println("Begin Run Time: " + new Date().toString());
  Thread.sleep(3000);
  System.out.println("End Run Time: " + new Date().toString());
  runCount++;
  if (runCount == 3) {
   timer.cancel();
  }
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
 }
 }
 public static void main(String[] args) {
 try {
  MyTask task = new MyTask();
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  String dateStr = "2016-12-27 14:36:00";
  Date date = sdf.parse(dateStr);
  System.out.println("Date = " + date.toString() + " NowTime = " + new Date().toString());
  timer.schedule(task, date, 5000);
 } catch (ParseException e) {
  e.printStackTrace();
 }
 }
}

执行结果

早于当前基准时间

Date = Tue Dec 27 14:36:00 CST 2016 NowTime = Tue Dec 27 22:23:37 CST 2016
Begin Run Time: Tue Dec 27 22:23:37 CST 2016
End Run Time: Tue Dec 27 22:23:40 CST 2016
Begin Run Time: Tue Dec 27 22:23:42 CST 2016
End Run Time: Tue Dec 27 22:23:45 CST 2016
Begin Run Time: Tue Dec 27 22:23:47 CST 2016
End Run Time: Tue Dec 27 22:23:50 CST 2016

Process finished with exit code 0

晚于当前基准时间

Date = Tue Dec 27 22:42:00 CST 2016 NowTime = Tue Dec 27 22:41:54 CST 2016
Begin Run Time: Tue Dec 27 22:42:00 CST 2016
End Run Time: Tue Dec 27 22:42:03 CST 2016
Begin Run Time: Tue Dec 27 22:42:05 CST 2016
End Run Time: Tue Dec 27 22:42:08 CST 2016
Begin Run Time: Tue Dec 27 22:42:10 CST 2016
End Run Time: Tue Dec 27 22:42:13 CST 2016

Process finished with exit code 0

不管早还是晚于基准时间,都不进行补偿,下一次任务的执行时间参考的是上一次任务的开始时间点来计算。

schedule延时

使用示例

public class Demo {
 private static Timer timer = new Timer();
 private static int runCount = 0;
 public static class MyTask extends TimerTask {
 @Override
 public void run() {
  try {
  System.out.println("Begin Run Time: " + new Date().toString());
  Thread.sleep(5000);
  System.out.println("End Run Time: " + new Date().toString());
  runCount++;
  if (runCount == 3) {
   timer.cancel();
  }
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
 }
 }
 public static void main(String[] args) {
 try {
  MyTask task = new MyTask();
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  String dateStr = "2016-12-27 22:42:00";
  Date date = sdf.parse(dateStr);
  System.out.println("Date = " + date.toString() + " NowTime = " + new Date().toString());
  timer.schedule(task, date, 3000);
 } catch (ParseException e) {
  e.printStackTrace();
 }
 }
}

执行结果

早于当前基准时间

Date = Tue Dec 27 22:42:00 CST 2016 NowTime = Tue Dec 27 22:45:17 CST 2016
Begin Run Time: Tue Dec 27 22:45:17 CST 2016
End Run Time: Tue Dec 27 22:45:22 CST 2016
Begin Run Time: Tue Dec 27 22:45:22 CST 2016
End Run Time: Tue Dec 27 22:45:27 CST 2016
Begin Run Time: Tue Dec 27 22:45:27 CST 2016
End Run Time: Tue Dec 27 22:45:32 CST 2016

Process finished with exit code 0

晚于当前基准时间

Date = Tue Dec 27 22:47:00 CST 2016 NowTime = Tue Dec 27 22:46:27 CST 2016
Begin Run Time: Tue Dec 27 22:47:00 CST 2016
End Run Time: Tue Dec 27 22:47:05 CST 2016
Begin Run Time: Tue Dec 27 22:47:05 CST 2016
End Run Time: Tue Dec 27 22:47:10 CST 2016
Begin Run Time: Tue Dec 27 22:47:10 CST 2016
End Run Time: Tue Dec 27 22:47:15 CST 2016

Process finished with exit code 0

不管早还是晚于当前基准时间,都不进行补偿,下一次任务的执行时间都是参考上一次任务结束的时间点来计算。

scheduleAtFixedRate不延时

使用示例

public class Demo {
 private static Timer timer = new Timer();
 private static int runCount = 0;
 public static class MyTask extends TimerTask {
 @Override
 public void run() {
  try {
  System.out.println("Begin Run Time: " + new Date().toString());
  Thread.sleep(3000);
  System.out.println("End Run Time: " + new Date().toString());
  runCount++;
  if (runCount == 1000) {
   timer.cancel();
  }
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
 }
 }
 public static void main(String[] args) {
 try {
  MyTask task = new MyTask();
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  String dateStr = "2016-12-27 22:51:42";
  Date date = sdf.parse(dateStr);
  System.out.println("Date = " + date.toString() + " NowTime = " + new Date().toString());
  timer.scheduleAtFixedRate(task, date, 5000);
 } catch (ParseException e) {
  e.printStackTrace();
 }
 }
}

执行结果

早于当前基准时间

Date = Tue Dec 27 22:51:42 CST 2016 NowTime = Tue Dec 27 22:51:57 CST 2016
Begin Run Time: Tue Dec 27 22:51:57 CST 2016
End Run Time: Tue Dec 27 22:52:00 CST 2016
Begin Run Time: Tue Dec 27 22:52:00 CST 2016
End Run Time: Tue Dec 27 22:52:03 CST 2016
Begin Run Time: Tue Dec 27 22:52:03 CST 2016
End Run Time: Tue Dec 27 22:52:06 CST 2016
Begin Run Time: Tue Dec 27 22:52:06 CST 2016
End Run Time: Tue Dec 27 22:52:09 CST 2016
Begin Run Time: Tue Dec 27 22:52:09 CST 2016
End Run Time: Tue Dec 27 22:52:12 CST 2016
Begin Run Time: Tue Dec 27 22:52:12 CST 2016
End Run Time: Tue Dec 27 22:52:15 CST 2016
Begin Run Time: Tue Dec 27 22:52:15 CST 2016
End Run Time: Tue Dec 27 22:52:18 CST 2016
Begin Run Time: Tue Dec 27 22:52:18 CST 2016
End Run Time: Tue Dec 27 22:52:21 CST 2016
Begin Run Time: Tue Dec 27 22:52:22 CST 2016
End Run Time: Tue Dec 27 22:52:25 CST 2016
Begin Run Time: Tue Dec 27 22:52:27 CST 2016
End Run Time: Tue Dec 27 22:52:30 CST 2016
Begin Run Time: Tue Dec 27 22:52:32 CST 2016
End Run Time: Tue Dec 27 22:52:35 CST 2016
Begin Run Time: Tue Dec 27 22:52:37 CST 2016
End Run Time: Tue Dec 27 22:52:40 CST 2016
Begin Run Time: Tue Dec 27 22:52:42 CST 2016
End Run Time: Tue Dec 27 22:52:45 CST 2016
Begin Run Time: Tue Dec 27 22:52:47 CST 2016
End Run Time: Tue Dec 27 22:52:50 CST 2016
Begin Run Time: Tue Dec 27 22:52:52 CST 2016
End Run Time: Tue Dec 27 22:52:55 CST 2016
Begin Run Time: Tue Dec 27 22:52:57 CST 2016
End Run Time: Tue Dec 27 22:53:00 CST 2016

Process finished with exit code 0

晚于当前基准时间

Date = Tue Dec 27 22:37:00 CST 2016 NowTime = Tue Dec 27 22:36:06 CST 2016
Begin Run Time: Tue Dec 27 22:37:00 CST 2016
End Run Time: Tue Dec 27 22:37:03 CST 2016
Begin Run Time: Tue Dec 27 22:37:05 CST 2016
End Run Time: Tue Dec 27 22:37:08 CST 2016
Begin Run Time: Tue Dec 27 22:37:10 CST 2016
End Run Time: Tue Dec 27 22:37:13 CST 2016

Process finished with exit code 0

不延时的情况下,当早于基准时间时,时间差内的执行任务未补偿完时,下一次执行任务的时间参考的是上一次执行任务的结束时间;一旦补偿完毕(注意粗体时间点),下一次执行任务的时间参考的是上一次执行任务的开始时间;当晚于基准时间时,下一次执行任务的时间参考的是上一次执行任务的开始时间。

scheduleAtFixedRate延时

使用示例

public class Demo {
 private static Timer timer = new Timer();
 private static int runCount = 0;
 public static class MyTask extends TimerTask {
 @Override
 public void run() {
  try {
  System.out.println("Begin Run Time: " + new Date().toString());
  Thread.sleep(5000);
  System.out.println("End Run Time: " + new Date().toString());
  runCount++;
  if (runCount == 3) {
   timer.cancel();
  }
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
 }
 }
 public static void main(String[] args) {
 try {
  MyTask task = new MyTask();
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  String dateStr = "2016-12-27 22:28:00";
  Date date = sdf.parse(dateStr);
  System.out.println("Date = " + date.toString() + " NowTime = " + new Date().toString());
  timer.scheduleAtFixedRate(task, date, 3000);
 } catch (ParseException e) {
  e.printStackTrace();
 }
 }
}

执行结果

早于当前基准时间

Date = Tue Dec 27 23:01:00 CST 2016 NowTime = Tue Dec 27 23:01:19 CST 2016
Begin Run Time: Tue Dec 27 23:01:19 CST 2016
End Run Time: Tue Dec 27 23:01:24 CST 2016
Begin Run Time: Tue Dec 27 23:01:24 CST 2016
End Run Time: Tue Dec 27 23:01:29 CST 2016
Begin Run Time: Tue Dec 27 23:01:29 CST 2016
End Run Time: Tue Dec 27 23:01:34 CST 2016
Begin Run Time: Tue Dec 27 23:01:34 CST 2016
End Run Time: Tue Dec 27 23:01:39 CST 2016

晚于当前基准时间

Date = Tue Dec 27 22:28:00 CST 2016 NowTime = Tue Dec 27 22:27:55 CST 2016
Begin Run Time: Tue Dec 27 22:28:00 CST 2016
End Run Time: Tue Dec 27 22:28:05 CST 2016
Begin Run Time: Tue Dec 27 22:28:05 CST 2016
End Run Time: Tue Dec 27 22:28:10 CST 2016
Begin Run Time: Tue Dec 27 22:28:10 CST 2016
End Run Time: Tue Dec 27 22:28:15 CST 2016

Process finished with exit code 0

延时的情况下,即使是早于基准时间,由于延时效应,根本不可能补偿完毕时间差内的执行任务,故而在延时的情况下,下一次任务的执行时间都是参考上一次任务结束的时间来计算。

对比总结

执行任务不延时 执行任务延时
早于当前基准时间 schedule:下一次任务的执行时间参考的是上一次任务的开始时间来计算。 scheduleAtFixedRate:当早于基准时间时,时间差内的执行任务未补偿完时,下一次执行任务的时间参考的是上一次任务的结束时间;一旦补偿完毕,下一次执行任务的时间参考上一次任务的开始时间来计算。 二者一样。下一次任务的执行时间都是参考上一次任务的结束时间来计算。
晚于当前基准时间 二者一样。下一次任务的执行时间参考的是上一次任务的开始时间来计算。 二者一样。下一次任务的执行时间都是参考上一次任务的结束时间来计算。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • java Quartz定时器任务与Spring task定时的几种实现方法

    一.分类 从实现的技术上来分类,目前主要有三种技术(或者说有三种产品): 1.Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可以让你的程序按照某一个频度执行,但不能在指定时间运行.一般用的较少,这篇文章将不做详细介绍. 2.使用Quartz,这是一个功能比较强大的的调度器,可以让你的程序在指定时间执行,也可以按照某一个频度执行,配置起来稍显复杂,稍后会详细介绍. 3.Spring3.0以后自带的task,可以将它看成一

  • 解析Java中的定时器及使用定时器制作弹弹球游戏的示例

    在我们编程过程中如果需要执行一些简单的定时任务,无须做复杂的控制,我们可以考虑使用JDK中的Timer定时任务来实现.下面LZ就其原理.实例以及Timer缺陷三个方面来解析java Timer定时器. 一.简介       在java中一个完整定时任务需要由Timer.TimerTask两个类来配合完成. API中是这样定义他们的,Timer:一种工具,线程用其安排以后在后台线程中执行的任务.可安排任务执行一次,或者定期重复执行.由TimerTask:Timer 安排为一次执行或重复执行的任务.

  • Java中Spring使用Quartz任务调度定时器

    Quartz 任务调度是什么 Quartz 是 OpenSymphony 开源组织在 Job scheduling 领域又一个开源项目,它可以与 J2EE 与 J2SE 应用程序相结合也可以单独使用.Quartz 是一个完全由 Java 编写的开源作业调度框架.不要让作业调度这个术语吓着你.尽管Quartz框架整合了许多额外功能,但就其简易形式看,你会发现它易用得简直让人受不了! 其实,他还是没有解释明白,我简单说一下:Quartz 作业调度就是可以实现定时任务.它可以实现类似 Windows

  • JAVA中 Spring定时器的两种实现方式

    目前有两种流行Spring定时器配置:Java的Timer类和OpenSymphony的Quartz. 1.Java Timer定时 首先继承java.util.TimerTask类实现run方法 import java.util.TimerTask; public class EmailReportTask extends TimerTask{ @Override public void run() { ... } } 在Spring定义 ... 配置Spring定时器 <bean id=&quo

  • Java 定时器(Timer)及线程池里使用定时器实例代码

    java Timer定时器 简单实例代码: public class Test { public static void main(String[] args) { // Timer定时器 Timer mTimer = new Timer(); MyTack myTack = new MyTack(); mTimer.schedule(myTack, 2000, 3000);//第一个参数是需要执行的任务 第二个参数是延迟多少时间最开始执行,第三个参数是执行完后多少时间后进行再次执行是一个周期性

  • jdk自带定时器使用方法详解

    首先看一下jdk自带定时器: 一种工具,线程用其安排以后在后台线程中执行的任务.可安排任务执行一次,或者定期重复执行.与每个 Timer 对象相对应的是单个后台线程,用于顺序地执行所有计时器任务.计时器任务应该迅速完成.如果完成某个计时器任务的时间太长,那么它会"独占"计时器的任务执行线程.因此,这就可能延迟后续任务的执行,而这些任务就可能"堆在一起",并且在上述不友好的任务最终完成时才能够被快速连续地执行. schedule(TimerTask task,long

  • java当中的定时器的4种使用方式

    对于开发游戏项目的同胞来说,Timer 这个东西肯定不会陌生,今天对以前自己经常使用的定时进行了一番小小的总结!没有写具体实现的原理,只是列举出了其中的四种比较常见的使用方法,相对而言,所以只要按照其所列举的例子仿照即可! import java.util.Calendar; import java.util.Date; import java.util.Timer; import java.util.TimerTask; public class TimeTest { public stati

  • Java 定时器(Timer,TimerTask)详解及实例代码

     Java 定时器 在JAVA中实现定时器功能要用的二个类是Timer,TimerTask Timer类是用来执行任务的类,它接受一个TimerTask做参数 Timer有两种执行任务的模式,最常用的是schedule,它可以以两种方式执行任务:1:在某个时间(Data),2:在某个固定的时间之后(int delay).这两种方式都可以指定任务执行的频率,本文有二个例子,一个是简单的一个是用了内部类 1.简单实例 先写一个类 public class TimeTest { public stat

  • java实现多线程之定时器任务

    在Java中Timer是java.util包中的一个工具类,提供了定时器的功能.我们可以创建一个Timer对象,然后调用其schedule方法在某个特定的时间去执行一个特定的任务.并且你可以让其以特定频率一直执行某个任务,这个任务是用TimerTask来描述的,我们只需要将要进行的操作写在TimerTask类的run方法中即可.先附上两个小例子一遍让读者了解什么是定时器.接着再分析其中的一些源码实现. 第一个小例子: package com.zkn.newlearn.thread; import

  • java使用TimerTask定时器获取指定网络数据

    复制代码 代码如下: import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.URL;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask; public class GetYinInf

随机推荐