Java定时器

Python015

Java定时器,第1张

好多朋友用过Windows的任务计划 也有不少程序迷自己曾写过时钟报警 系统自动关机等趣味程序 可却很少有朋友在Web工程中实现过类似功能

当Web工程启动时 定时器能自动开始计时 在整个Web工程的生命期里 定时器能在每晚深夜触发一次任务 因此定时器的存放位置也值得考查 不能简单的存在于单个Servlet或JavaBean中 必须能让定时器宿主的存活期为整个Web工程生命期 在工程启动时能自动加载运行 结合这两点 跟 Servlet上下文有关的侦听器就最合适不过了 通过在工程的配置文件中加以合理配置 会在工程启动时自动运行 并在整个工程生命期中处于监听状态

下面就Servlet侦听器结合Java定时器来讲述整个实现过程 要运用Servlet侦听器需要实现 javax servlet ServletContextListener接口 同时实现它的contextInitialized (ServletContextEvent event)和contextDestroyed(ServletContextEvent event)两个接口函数 考虑定时器有个建立和销毁的过程 看了前面两个接口函数 就不容置疑的把建立的过程置入 contextInitialized 把销毁的过程置入contextDestroyed了

我把ServletContextListener的实现类取名为ContextListener 在其内添加一个定时器 示例代码如下所示

import java util Timer

import javax servlet ServletContextEvent

import javax servlet ServletContextListener

import javax servlet ServletException

import javax servlet ServletRequest

import javax servlet ServletResponse

import javax servlet HttpServlet

public class ContextListener

extends HttpServlet

implements ServletContextListener {

public ContextListener() {

}

private java util Timer timer = null

public void contextInitialized(ServletContextEvent event) {

timer = new java util Timer(true)

event getServletContext() log( 定时器已启动 )

timer schedule(new MyTask(event getServletContext()) * * )

event getServletContext() log( 已经添加任务调度表 )

}

public void contextDestroyed(ServletContextEvent event) {

timer cancel()

event getServletContext() log( 定时器销毁 )

}

}

以上代码中 timer schedule(new MyTask(event getServletContext()) * * )这一行为定时器调度语句 其中MyTask是自定义需要被调度的执行任务(在我的财政数据中心项目中就是报表计算引擎入口) 从 java util TimerTask继承 下面会重点讲述 第三个参数表示每小时(即 * * 毫秒)被触发一次 中间参数 表示无延迟 其它代码相当简单 不再详细说明

下面介绍MyTask的实现 上面的代码中看到了在构造MyTask时 传入了javax servlet ServletContext类型参数 是为记录Servlet日志方便而传入 因此需要重载MyTask的构造函数(其父类java util TimerTask原构造函数是没有参数的) 在timer schedule()的调度中 设置了每小时调度一次 因此如果想实现调度任务每 小时被执行一次 还需要判断一下时钟点 以常量C_SCHEDULE_HOUR表示(晚上 点 也即 点) 同时为防止 小时执行下来 任务还未执行完(当然 一般任务是没有这么长的) 避免第二次又被调度以引起执行冲突 设置了当前是否正在执行的状态标志isRunning 示例代码如下所示

import java util *

import javax servlet ServletContextEvent

import javax servlet ServletContextListener

import javax servlet ServletException

import javax servlet ServletRequest

import javax servlet ServletResponse

import javax servlet HttpServlet

import javax servlet *

public class MyTask extends TimerTask {

private static final int C_SCHEDULE_HOUR =

private static boolean isRunning = false

private ServletContext context = null

public MyTask() {

}

public MyTask(ServletContext context) {

ntext = context

}

public void run() {

Calendar cal = Calendar getInstance()

if (!isRunning) {

if (C_SCHEDULE_HOUR == cal get(Calendar HOUR_OF_DAY)) {

isRunning = true

context log( 开始执行指定任务 )

//TODO 添加自定义的详细任务 以下只是示例

//系统定时接收邮件

Email email=new Email()

email recieve()

isRunning = false

context log( 指定任务执行结束 )

}

}

else {

context log( 上一次任务执行还未结束 )

}

}

}

到这儿 ServletContextListener和MyTask的代码都已完整了 最后一步就是把ServletContextListener部署到您的Web工程中去 在您工程的web xml配置文件中加入如下三行

<listener>

<listener class>test ContextListener</listener class>

</listener>

lishixinzhi/Article/program/Java/hx/201311/26421

JDK 自带的定时器实现

// schedule(TimerTask task, long delay) 延迟 delay 毫秒 执行

// schedule(TimerTask task, Date time) 特定时间执行

public static void main(String[] args) {

for (int i = 0i <10++i) {

new Timer("timer - " + i).schedule(new TimerTask() {

@Override

public void run() {

println(Thread.currentThread().getName() + " run ")

}

}, 1000)

}

}

2. Quartz 定时器实现

//首先我们需要定义一个任务类,比如为MyJob02 ,

//该类需要继承Job类,然后添加execute(JobExecutionContext context)方法,在

//这个方法中就是我们具体的任务执行的地方。

//由希望由调度程序执行的组件实现的接口

public class MyJob02 implements Job {

@Override

public void execute(JobExecutionContext context) throws JobExecutionException {

// TODO Auto-generated method stub

// 执行响应的任务.

System.out.println("HelloJob.execute,"+new Date())

}

}

public class QuartzTest5 {

public static void main(String[] args) throws Exception {

//SchedulerFactory 是一个接口,用于Scheduler的创建和管理

SchedulerFactory factory = new StdSchedulerFactory()

//从工厂里面拿到一个scheduler实例

//计划表(可能翻译的不太贴切),现在我们有了要做的内容,

//与调度程序交互的主要API

/*

* Scheduler的生命期,从SchedulerFactory创建它时开始,

到Scheduler调用shutdown()方法时结束;Scheduler被创建后,

可以增加、删除和列举Job和Trigger,以及执行其它与调度相关的操作

(如暂停Trigger)。但是,Scheduler只有在调用start()方法后,

才会真正地触发trigger(即执行job)

*/

Scheduler scheduler = factory.getScheduler()

//具体任务.

//用于定义作业的实例

//JobBuilder - 用于定义/构建JobDetail实例,用于定义作业的实例。

JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("job1", "group1").build()

//Trigger(即触发器) - 定义执行给定作业的计划的组件

//TriggerBuilder - 用于定义/构建触发器实例

CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")

.withSchedule(CronScheduleBuilder.cronSchedule("0/1  * * * * ?")).build()

scheduler.scheduleJob(job, trigger)

scheduler.start()

}

3. Spring  boot 任务调度(这个非常容易实现)

/*

*  开启对定时任务的支持

*  在相应的方法上添加@Scheduled声明需要执行的定时任务。

*/

@EnableScheduling

//@EnableScheduling注解来开启对计划任务的支持

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args)

}

}

@Component

public class ScheduledTasks {

private Logger logger = LoggerFactory.getLogger(ScheduledTasks.class)

private    int     i=0

//0 0 0 2 * ?

@Scheduled(cron="*  *  *  2  *  ?")

//@Scheduled 注解用于标注这个方法是一个定时任务的方法

public void testFixDelay() {

logger.info("执行方法"+i++)

}

用java实现一个计时器的方法:

public class TestDingShi implements Runnable

{

Thread xc

Dao dao=new DaoImpl()

public TestDingShi()

{

xc=new Thread(this)//线程开启

xc.start()

}

public void run()

{

while (true)

{

try

{

xc.sleep(1000)//睡眠开始计时

}

catch (InterruptedException e)

{

// TODO Auto-generated catch block

e.printStackTrace()

}

//TODO定时在此

}

}

}