ScheduleIterator接口

import java.util.Date;

public interface ScheduleIterator 
{
    public Date next();//获取下一个触发的时间点
}

Scheduler类

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

public class Scheduler 
{
    class SchedulerTimerTask extends TimerTask 
    {
        private SchedulerTask schedulerTask;
        private ScheduleIterator iterator;
        public SchedulerTimerTask(SchedulerTask schedulerTask,ScheduleIterator iterator)
        {
            this.schedulerTask = schedulerTask;
            this.iterator = iterator;
        }
        public void run() 
        {
            schedulerTask.run();
            reschedule(schedulerTask, iterator);
        }
    }

private final Timer timer = new Timer();

public Scheduler() 
    {
    }
    public void cancel() 
    {
        timer.cancel();
    }
    public void schedule(SchedulerTask schedulerTask,ScheduleIterator iterator) 
    {
        Date time = iterator.next();
        if (time == null) 
        {
            schedulerTask.cancel();
        }
        else 
        {
            synchronized(schedulerTask.lock)
            {
                if (schedulerTask.state != SchedulerTask.VIRGIN) 
                {
                    throw new IllegalStateException("Task already scheduled " +
                        "or cancelled");
                }
                schedulerTask.state = SchedulerTask.SCHEDULED;
                schedulerTask.timerTask = new SchedulerTimerTask(schedulerTask, iterator);
                timer.schedule(schedulerTask.timerTask, time);
            }
        }
    }

private void reschedule(SchedulerTask schedulerTask,ScheduleIterator iterator)
    {
        Date time = iterator.next();
        if (time == null)
        {
            schedulerTask.cancel();
        } 
        else 
        {
            synchronized(schedulerTask.lock)
            {
                if (schedulerTask.state != SchedulerTask.CANCELLED) 
                {
                    schedulerTask.timerTask = new SchedulerTimerTask(schedulerTask, iterator);
                    timer.schedule(schedulerTask.timerTask, time);
                }
            }
        }
    }
}

SchedulerTask 类

import java.util.TimerTask;

public abstract class SchedulerTask implements Runnable 
{//被调度器不断调度执行的任务

final Object lock = new Object();

int state = VIRGIN;//任务状态
    static final int VIRGIN = 0;
    static final int SCHEDULED = 1;
    static final int CANCELLED = 2;

TimerTask timerTask;//底层的定时器任务
    protected SchedulerTask() 
    {
    }
    public abstract void run();//调度任务执行的具体任务
    public boolean cancel() 
    {
        synchronized(lock) 
        {
            if (timerTask != null) 
            {
                timerTask.cancel();//取消任务
            }
            boolean result = (state == SCHEDULED);//任务已经被调度执行
            state = CANCELLED;//设置任务状态为“取消”
            return result;
        }
    }
    public long scheduledExecutionTime()
    {
        synchronized(lock) 
        {
            return timerTask == null ? 0 : timerTask.scheduledExecutionTime();//任务执行时间
        }
    }

}

DailyIterator类:

import java.util.Calendar;
import java.util.Date;

public class DailyIterator implements ScheduleIterator {
    private final int hourOfDay, minute, second;
    private final Calendar calendar = Calendar.getInstance();

public DailyIterator(int hourOfDay, int minute, int second)
    {
        this(hourOfDay, minute, second, new Date());
    }

public DailyIterator(int hourOfDay, int minute, int second, Date date)
    {
        this.hourOfDay = hourOfDay;
        this.minute = minute;
        this.second = second;
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);
        calendar.set(Calendar.MILLISECOND, 0);
        if (!calendar.getTime().before(date)) 
        {
            calendar.add(Calendar.DATE, -1);
        }
    }

public Date next()
    {//获取下一个触发的时间点
        calendar.add(Calendar.DATE, 1);
        return calendar.getTime();
    }

}

测试类:

import java.text.SimpleDateFormat;

import java.util.Date;

import org.tiling.scheduling.Scheduler;
import org.tiling.scheduling.SchedulerTask;
import org.tiling.scheduling.examples.iterators.DailyIterator;

public class AlarmClock 
{

private final Scheduler scheduler = new Scheduler();//调度器
    private final SimpleDateFormat dateFormat =
        new SimpleDateFormat("dd MMM yyyy HH:mm:ss.SSS");
    private final int hourOfDay, minute, second;//每天触发的时间点

public AlarmClock(int hourOfDay, int minute, int second) 
    {
        this.hourOfDay = hourOfDay;
        this.minute = minute;
        this.second = second;
    }

public void start() 
    {
        scheduler.schedule(new SchedulerTask() 
        {
            public void run() 
            {
                soundAlarm();
            }
            private void soundAlarm()
            {
                System.out.println("Wake up! " +
                    "It's " + dateFormat.format(new Date()));
                // Start a new thread to sound an alarm
            }
        }, new DailyIterator(hourOfDay, minute, second));//通过迭代器模式迭代遍历得到后面一系列的时间点
    }

public static void main(String[] args) 
    {
        AlarmClock alarmClock = new AlarmClock(22, 5, 0);
        alarmClock.start();
    }
}

参考资料

Scheduling recurring tasks in Java applications

作者:洞庭散人

出处:http://phinecos.cnblogs.com/    

本博客遵从Creative Commons Attribution 3.0 License,若用于非商业目的,您可以自由转载,但请保留原作者信息和文章链接URL。

一个java定时器框架的更多相关文章

  1. 【通信】Netty JBOSS提供的一个java开源框架

    Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序dsf. 也就是说,Netty 是一个基 ...

  2. Java微框架:不可忽视的新趋势--转载

    原文:http://www.infoq.com/cn/news/2015/06/Java-Spark-Jodd-Ninja?utm_campaign=infoq_content&utm_sou ...

  3. Java NIO框架Netty demo

    Netty是什么 Netty是一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序. 也就是说,Netty 是一个基于NI ...

  4. Java 日志框架终极教程

    概述 对于现代的 Java 应用程序来说,只要被部署到真实的生产环境,其日志的重要性就是不言而喻的,很难想象没有任何日志记录功能的应用程序被运行于生产环境中.日志 API 所能提供的功能是多种多样的, ...

  5. [Java定时器]用Spring Task实现一个简单的定时器.

    今天做一个项目的的时候需要用到定时器功能.具体需求是: 每个月一号触发一次某个类中的方法去拉取别人的接口获取上一个月份车险过期的用户.如若转载请附上原文链接:http://www.cnblogs.co ...

  6. 自己写一个java的mvc框架吧(二)

    自己写一个mvc框架吧(二) 自己写代码的习惯 写一个框架吧,如果这个框架会用到一些配置上的东西,我自己习惯是先不用考虑这个配置文件应该是怎样的,什么形式的,先用一个java对象(比如叫 Config ...

  7. 自己写一个java的mvc框架吧(一)

    自己写一个mvc框架吧(一) 目录 自己写一个mvc框架吧(一) 自己写一个mvc框架吧(二) 自己写一个mvc框架吧(三) 自己写一个mvc框架吧(四) 写之前的一些废话 废话 1 (总是要先随便说 ...

  8. 从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射

    从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射.Collection 接口又有 3 ...

  9. 一个Java语言所写的shop网站框架明细

    核心框架Spring Framework :作为一个优秀的开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用 ...

随机推荐

  1. Alpha-beta pruning

    function alphabeta(node, depth, α, β, maximizingPlayer) or node is a terminal node return the heuris ...

  2. 洛谷 First Step (ファーストステップ) 3月月赛T1

    题目背景 知らないことばかりなにもかもが(どうしたらいいの?) 一切的一切 尽是充满了未知数(该如何是好) それでも期待で足が軽いよ(ジャンプだ!) 但我仍因满怀期待而步伐轻盈(起跳吧!) 温度差なん ...

  3. cocoapods学习

    1.安装 http://stackoverflow.com/questions/16459028/rvm-install-error-running-requirements-osx-port-ins ...

  4. FATAL org.apache.hadoop.hdfs.server.datanode.DataNode: Initialization failed for Block pool <registering> (Datanode Uuid unassigned) service to controller/192.168.1.183:9000. Exiting. java.io.IOExcep

    2018-01-09 09:47:38,297 FATAL org.apache.hadoop.hdfs.server.datanode.DataNode: Initialization failed ...

  5. Mybatis-Generator逆向生成Po,Mapper,XMLMAPPER(idea)

    前文有一篇手工生成的说明,地址: http://www.cnblogs.com/xiaolive/p/4874605.html, 现在这个补充一下在idea里面的自动版本的数据库逆向生成工具: 一.g ...

  6. Web性能优化系列:10个JavaScript性能提升的技巧

    由 伯乐在线 - Delostik 翻译,黄利民 校稿.未经许可,禁止转载!英文出处:jonraasch.com.欢迎加入翻译小组. Nicholas Zakas是一位 JS 大师,Yahoo! 首页 ...

  7. 在行列都排好序的矩阵中找数 【题目】 给定一个有N*M的整型矩阵matrix和一个整数K, matrix的每一行和每一 列都是排好序的。实现一个函数,判断K 是否在matrix中。 例如: 0 1 2 5 2 3 4 7 4 4 4 8 5 7 7 9 如果K为7,返回true;如果K为6,返 回false。 【要求】 时间复杂度为O(N+M),额外空间复杂度为O(1)。

    从对角考虑 package my_basic.class_3; /** * 从对角开始 */ public class Code_09_FindNumInSortedMatrix { public s ...

  8. Bootstrap历练实例:警告样式按钮

    <!DOCTYPE html><html><head> <meta http-equiv="Content-Type" content=& ...

  9. 分布式mysql 和 zk ( zookeeper )的分布式的区别 含冷热数据讨论

    zk ( zookeeper )的分布式仅仅指的是备份模式. 分布式 mysql 不仅仅要关注备份(从以往的半主,主主,到 paxos). (mysql 比 hbase 的region成熟, hdfs ...

  10. Spring 概念及特点 Spring下载地址 控制反转IoC实现原理

    Spring下载地址 http://repo.springsource.org/libs-release-local/org/springframework/spring/ Spring是开源full ...