1、在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等。对于这样的操作最方便、高效的实现方式就是使用java.util.Timer工具类。

private java.util.Timer timer;
timer = new Timer(true);
timer.schedule(
new java.util.TimerTask() { public void run() { //server.checkNewMail(); 要操作的方法 } }, 0, 5*60*1000); 
      第一个参数是要操作的方法,第二个参数是要设定延迟的时间,第三个参数是周期的设定,每隔多长时间执行该操作。

使用这几行代码之后,Timer本身会每隔5分钟调用一遍server.checkNewMail()方法,不需要自己启动线程。Timer本身也是多线程同步的,多个线程可以共用一个Timer,不需要外部的同步代码。

 
2、
(1)Timer.schedule(TimerTask task,Date time)安排在制定的时间执行指定的任务。
(2)Timer.schedule(TimerTask task,Date firstTime ,long period)安排指定的任务在指定的时间开始进行重复的固定延迟执行.
(3)Timer.schedule(TimerTask task,long delay)安排在指定延迟后执行指定的任务.
(4)Timer.schedule(TimerTask task,long delay,long period)安排指定的任务从指定的延迟后开始进行重复的固定延迟执行.
(5)Timer.scheduleAtFixedRate(TimerTask task,Date firstTime,long period)安排指定的任务在指定的时间开始进行重复的固定速率执行.
(6)Timer.scheduleAtFixedRate(TimerTask task,long delay,long period)安排指定的任务在指定的延迟后开始进行重复的固定速率执行.
 
 

java timer 定时器

以下内容根据 The JavaTM Tutorial 和相关API doc翻译整理,以供日后参考:
1.概览
Timer是一种定时器工具,用来在一个后台线程计划执行指定任务。它可以计划执行一个任务一次或反复多次。
TimerTask一个抽象类,它的子类代表一个可以被Timer计划的任务。

简单的一个例程:

import java.util.Timer;
import java.util.TimerTask;

/**
* Simple demo that uses java.util.Timer to schedule a task to execute
* once 5 seconds have passed.
*/

public class Reminder {
    Timer timer;

    public Reminder(int seconds) {
        timer = new Timer();
        timer.schedule(new RemindTask(), seconds*1000);
    }

    class RemindTask extends TimerTask {
        public void run() {
            System.out.println("Time's up!");
            timer.cancel(); //Terminate the timer thread
        }
    }

    public static void main(String args[]) {
        System.out.println("About to schedule task.");
        new Reminder(5);
        System.out.println("Task scheduled.");
    }
}

运行这个小例子,你会首先看到:

About to schedule task.

5秒钟之后你会看到:

Time's up!

这个小例子可以说明一些用Timer线程实现和计划执行一个任务的基础步骤:

实现自定义的TimerTask的子类,run方法包含要执行的任务代码,在这个例子里,这个子类就是RemindTask。
实例化Timer类,创建计时器后台线程。
实例化任务对象 (new RemindTask()). 
制定执行计划。这里用schedule方法,第一个参数是TimerTask对象,第二个参数表示开始执行前的延时时间(单位是milliseconds,这里定义了5000)。还有一种方法可以指定任务的执行时间,如下例,指定任务在11:01 p.m.执行:
 //Get the Date corresponding to 11:01:00 pm today.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 1);
calendar.set(Calendar.SECOND, 0);
Date time = calendar.getTime();

timer = new Timer();
timer.schedule(new RemindTask(), time);

2.终止Timer线程
默认情况下,只要一个程序的timer线程在运行,那么这个程序就会保持运行。当然,你可以通过以下四种方法终止一个timer线程:

调用timer的cancle方法。你可以从程序的任何地方调用此方法,甚至在一个timer task的run方法里。
让timer线程成为一个daemon线程(可以在创建timer时使用new Timer(true)达到这个目地),这样当程序只有daemon线程的时候,它就会自动终止运行。 
当timer相关的所有task执行完毕以后,删除所有此timer对象的引用(置成null),这样timer线程也会终止。 
调用System.exit方法,使整个程序(所有线程)终止。 
Reminder

的例子使用了第一种方式。在这里不能使用第二种方式,因为这里需要程序保持运行直到timer的任务执行完成,如果设成daemon,那么当main线程
结束的时候,程序只剩下timer这个daemon线程,于是程序不会等timer线程执行task就终止了。

有些时候,程序的终止与

并不只与timer线程有关。举个例子,如果我们使用AWT来beep,那么AWT会自动创建一个非daemon线程来保持程序的运行。下面的代码我们对
Reminder做了修改,加入了beeping功能,于是我们需要加入System.exit的调用来终止程序。

import java.util.Timer;
import java.util.TimerTask;
import java.awt.Toolkit;

/**
* Simple demo that uses java.util.Timer to schedule a task to execute
* once 5 seconds have passed.
*/

public class ReminderBeep {
    Toolkit toolkit;
    Timer timer;

    public ReminderBeep(int seconds) {
        toolkit = Toolkit.getDefaultToolkit();
        timer = new Timer();
        timer.schedule(new RemindTask(), seconds*1000);
    }

    class RemindTask extends TimerTask {
        public void run() {
            System.out.println("Time's up!");
    toolkit.beep();
    //timer.cancel(); //Not necessary because we call System.exit
    System.exit(0);   //Stops the AWT thread (and everything else)
        }
    }

    public static void main(String args[]) {
System.out.println("About to schedule task.");
        new ReminderBeep(5);
System.out.println("Task scheduled.");
    }
}

3.反复执行一个任务

先看一个例子:

public class AnnoyingBeep {
    Toolkit toolkit;
    Timer timer;

    public AnnoyingBeep() {
        toolkit = Toolkit.getDefaultToolkit();
        timer = new Timer();
        timer.schedule(new RemindTask(),
               0,        //initial delay
               1*1000);  //subsequent rate
    }

    class RemindTask extends TimerTask {
        int numWarningBeeps = 3;

        public void run() {
            if (numWarningBeeps > 0) {
                toolkit.beep();
                System.out.println("Beep!");
                numWarningBeeps--;
            } else {
                toolkit.beep(); 
                System.out.println("Time's up!");
                //timer.cancel(); //Not necessary because we call System.exit
                System.exit(0);   //Stops the AWT thread (and everything else)
            }
        }
    }
    ...
}

执行,你会看到如下输出:

Task scheduled.
Beep!      
Beep!      //one second after the first beep
Beep!      //one second after the second beep
Time's up! //one second after the third beep

这里使用了三个参数的schedule方法用来指定task每隔一秒执行一次。如下所列为所有Timer类用来制定计划反复执行task的方法 : 
schedule(TimerTask task, long delay, long period) 
schedule(TimerTask task, Date time, long period) 
scheduleAtFixedRate(TimerTask task, long delay, long period) 
scheduleAtFixedRate(TimerTask task, Date firstTime, long period) 

计划反复执行的任务时,如果你注重任务执行的平滑度,那么请使用schedule方法,如果你在乎的是任务的执行频度那么使用
scheduleAtFixedRate方法。 例如,这里使用了schedule方法,这就意味着所有beep之间的时间间隔至少为1秒,也就是说,如
果有一个beap因为某种原因迟到了(未按计划执行),那么余下的所有beep都要延时执行。如果我们想让这个程序正好在3秒以后终止,无论哪一个
beep因为什么原因被延时,那么我们需要使用scheduleAtFixedRate方法,这样当第一个beep迟到时,那么后面的beep就会以最快
的速度紧密执行(最大限度的压缩间隔时间)。

4.进一步分析schedule和scheduleAtFixedRate

(1)
2个参数的schedule在制定任务计划时, 如果指定的计划执行时间scheduledExecutionTime<=
systemCurrentTime,则task会被立即执行。scheduledExecutionTime不会因为某一个task的过度执行而改变。
(2)
3个参数的schedule在制定反复执行一个task的计划时,每一次执行这个task的计划执行时间随着前一次的实际执行时间而变,也就是
scheduledExecutionTime(第n+1次)=realExecutionTime(第n次)+periodTime。也就是说如果第n
次执行task时,由于某种原因这次执行时间过长,执行完后的systemCurrentTime>=
scheduledExecutionTime(第n+1次),则此时不做时隔等待,立即执行第n+1次task,而接下来的第n+2次task的
scheduledExecutionTime(第n+2次)就随着变成了realExecutionTime(第n+1次)+periodTime。说
白了,这个方法更注重保持间隔时间的稳定。
(3)3个参数的scheduleAtFixedRate在制定反复执行一个task的计划时,每一

执行这个task的计划执行时间在最初就被定下来了,也就是scheduledExecutionTime(第n次)=firstExecuteTime
+n*periodTime;如果第n次执行task时,由于某种原因这次执行时间过长,执行完后的systemCurrentTime>=
scheduledExecutionTime(第n+1次),则此时不做period间隔等待,立即执行第n+1次task,而接下来的第n+2次的
task的scheduledExecutionTime(第n+2次)依然还是firstExecuteTime+(n+2)*periodTime这
在第一次执行task就定下来了。说白了,这个方法更注重保持执行频率的稳定。

java关于Timer schedule执行定时任务 1、在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等的更多相关文章

  1. java关于Timer schedule执行定时任务 !!!!!!!!!

    1.在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等.对于这样的操作最方便.高效的实现方式就是使用java.util.Timer工具类. private java.util.Time ...

  2. java开发中的常见类和对象-建议阅读时间3分钟

    1.Dao 数据访问对象 此对象用于访问数据库.实现类一般用于用于操作数据库! 一般操作修改,添加,删除数据库操作的步骤很相似,就写了一个公共类DAO类 ,修改,添加,删除数据库操作时 直接调用公共类 ...

  3. 在AE二次开发中出“正试图在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。”异常解决方案

    今天的一个项目总用到了AE的开发组件,也就是ESRI公司提供的一系列的开发包(组件)都是以dll(动态链接库的形式)然后今天在调试的时候却出现了“正试图在 OS 加载程序锁内执行托管代码.不要尝试在 ...

  4. SSH开发中 使用超链接到action 其excute方法会被执行两次 actual row count: 0; expected: 1

    由于执行两次excute,所以在做删除操作的时候会出现 Batch update returned unexpected row count from update [0]; actual row c ...

  5. 线程 Timer TimerTask 计时器 定时任务 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  6. 如何在Spring Boot 中动态设定与执行定时任务

    本篇文章的目的是记录并实现在Spring Boot中,动态设定与执行定时任务. 我的开发项目是 Maven 项目,所以首先需要在 pom.xml 文件中加入相关的依赖.依赖代码如下所示: <de ...

  7. 使用Timer和ScheduledThreadPoolExecutor执行定时任务

    Java使用Timer和ScheduledThreadPoolExecutor执行定时任务 定时任务是在指定时间执行程序,或周期性执行计划任务.Java中实现定时任务的方法有很多,主要JDK自带的一些 ...

  8. 使用Timer执行定时任务

    一.Timer概述 在Java开发中,会碰到一些需要定时或者延时执行某些任务的需求,这时,我们可以使用Java中的Timer类实现. 二.Timer介绍 Timer是一个定时器类,通过该类可以为指定的 ...

  9. java中服务器启动时,执行定时任务

    package com.ripsoft.util; import java.util.Calendar; import java.util.Timer; import javax.servlet.Se ...

随机推荐

  1. Python框架之Django学习笔记(五)

    第一个Django网页小结 进来的请求转入/hello/. Django通过在ROOT_URLCONF配置来决定根URLconf. Django在URLconf中的所有URL模式中,查找第一个匹配/h ...

  2. Windows网络编程笔记6 --- WinSock I/O 控制方法

    Windows提供了两种方式“套接字模式”和“套接字I/O模型”,可对一个套接字上的I/O行为加以控制.套接字模式用于决定在随一个套接字调用时,那些 Winsock函数的行为.其中的模型包括括sele ...

  3. Leetcode 647.回文子串

    回文子串 给定一个字符串,你的任务是计算这个字符串中有多少个回文子串. 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串. 示例 1: 输入: "abc&qu ...

  4. jupyter-notebook快捷键的使用

    jupyter-notebook快捷键的使用 工具有个键盘图标可以看所有快捷键 Esc + F 在代码中查找.替换 Esc + O 在cell和输出结果间切换. Shift + J 或 Shift + ...

  5. iOS-------- Objective-C多态:动态类型识别+动态绑定+动态加载

    一.Objective-C多态 1.概念:相同接口,不同的实现 来自不同类可以定义共享相同名称的方法. 动态类型能使程序直到执行时才确定对象所属类型 动态类型绑定能使程序直到执行时才确定要对对象调用的 ...

  6. 利用jQuery无缝滚动插件liMarquee实现图片(链接)和文字(链接)向右无缝滚动(兼容ie7+)

    像新闻类的版块经常要求一条条的新闻滚动出现,要实现这种效果,可以使用jQuery无缝滚动插件liMarquee. 注意: 1. 它的兼容性是IE7+,及现代浏览器. 2. 引用的jquery的版本最好 ...

  7. 前端构建工具gulpjs的使用介绍及技巧(转)

    http://www.cnblogs.com/2050/p/4198792.html gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非常简单,学 ...

  8. webService的wsdl和restful的wadl的区别

    WebService之WADL和WSDL区别 两者都是基于自然语言描述的Web Application接口 . WADL主要用于Rest基础. Java开发WebService最重要的两个规范: JS ...

  9. python中文注释报错

    # -*- coding: utf-8 -*-#coding=utf-8 在开头加这个

  10. 【01】iconfont的使用

    我之前因为项目用bootstrap比较多,所以使用font awesome字体图标比较多,后来接触到了iconfont,发现想要的什么图标都有,还可以自定义图标,非常强大!之前看了一波教程,觉得繁琐, ...