短信发送平台,需要实现一个定时器,每个月1号早8点给特定人群发送短信
timer.scheduleAtFixedRate(timerTask, date, period);
第三个参数该怎么设?毕竟每个月的1号对应第三个参数不是固定值?

解决方案 »

  1.   

    用spring的定时任务就简单多了,想定义成咋样就定义成咋样,一个conExpress配置即可
      

  2.   

    谢谢楼上的两位
    Java里该如何搞定?
      

  3.   

    我知道哟个quartz框架,可以和Spring整合,很强大,你去看看吧
      

  4.   

    刚帮你搜了一个
    Spring+quartz的 下面的链接是详解,希望对你有帮助
    http://kai2008.javaeye.com/blog/435675
      

  5.   

    谢谢两位,只是,我现在是在做系统维护,之前的短信发送平台已经有实现每天给当天生日的员工发送生日祝福,所以我的选择只能是在java范围内搞定,并且做最小的改动,框架范围的实现方法我想对我来讲是没有实际意义的。
      

  6.   

    quartz正解,不用框架不是问题,quartz可以脱离框架使用的
      

  7.   


    是啊,单独使用quartz也是没问题的。
    lz参考一下这里官网的代码。http://www.quartz-scheduler.org/docs/cookbook/index.htmlgood luck
      

  8.   

    quartz是一个,操作系统的定时任务也可以
      

  9.   

    timer 本来就是简单的定时器,功能本来就简单。quartz的确应该选择。
      

  10.   

    我现在的做法是通过 Thread.sleep来实现的。启动系统的时候读取一下目标时间和实际时间进行比较,看是否应该执行任务,程序末尾的时候再读取一下当前时间和目标时间进行做差,转换成毫秒数,sleep一下。
      

  11.   

    Thread.sleep线和里.在学校的时候也作过一个.用毫秒弄的定时关机.这个应该会有用
      

  12.   

    建议看看SPRING里的定时器 和CROWN表达式 那个配置很方便
      

  13.   


    按照LZ的要求那么第三个参数就不是固定的了,而要每次都事先计算出来LZ要计算下个也有多少天噢  period = 1000 * 60 * 60 * 每月最后一天的日期
      

  14.   

    Java 里面要实现这样的定时任务还有比较麻烦的,不建议自己去实现,把 Quartz 这个框架的 jar 加进来吧。对于你的这个用途,只用 Quartz 就可以了,不需要用什么 Spring 集成的。如果需要自己实的话,可以使用 java.util.concurrent.DelayQueue,这个称为延迟队列,是 Java 集合框架的实现之一。存放进去的对象必须实现 java.util.concurrent.Delayed 和 java.lang.Comparable<T> 接口。在 Delayed 接口实现 public long getDelay(TimeUnit unit) 方法,如果在计算时返回值是小于等于 0 的话,那么在 DelayQueue 中使用 take 方法可以将其取出来。我们可以在第一次往 DelayQueue 塞任务的时候,把下一次要执行的毫秒保存到这个任务对象中去。等时间一到,那 take 由阻塞状态变为运行状态,会将其中超时的对象取出来。取出来之后,计算下一次运行的毫秒数,再将这个对象塞回队列中去,同时在外部还有这个对象的引用,使用 ExecuteService 接口 submit 执行一次。自己要实现这样的任务调度非常麻烦。这个是我写的小例子作为参考(没有使用 ScheduledExecutorService 类)。任务调度时间是每分钟执行一次(为了便利起见,全写在一个 java 文件中了)。import java.util.Calendar;
    import java.util.concurrent.DelayQueue;
    import java.util.concurrent.Delayed;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;public class DelayQueueTest {    public static void main(String[] args) throws InterruptedException {        SchedulerManager manager = new SchedulerManager();
            manager.addJob(new EveryMinuteDelay(new MyJob()));
            manager.start();        printCurrentTime();
            sleepMinutes(3);           // 休息 3 分钟后关掉
            manager.stop();     // 停止工作
            printCurrentTime();
        }    private static void sleepMinutes(long minutes) {
            try {
                TimeUnit.MINUTES.sleep(minutes);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }    private static void printCurrentTime() {
            System.out.printf("Current: %tF %<tT%n", System.currentTimeMillis());
        }
    }/**
     * <p>任务调度管理器</p>
     *
     * 2010-5-28 下午11:30:20
     */
    class SchedulerManager {    private ExecutorService executor;
        private DelayQueue<JobDelayed> jobs;
        private Scheduler scheduler;    public SchedulerManager() {
            this(1);
        }    /**
         * 根据线程池中线程数量构造调度管理器
         * @param threadPool
         */
        public SchedulerManager(int threadPool) {
            this.jobs = new DelayQueue<JobDelayed>();
            // 由于调度管理器需要占用一个线程,因此需要加 1
            this.executor = Executors.newFixedThreadPool(threadPool + 1);
            this.scheduler = new Scheduler(this);
        }    /**
         * <p>添加需要计划的任务</p>
         *
         * @param job
         */
        public void addJob(JobDelayed jobDelayed) {
            jobDelayed.nextTime();  // 计算下一次执行的时间
            jobs.put(jobDelayed);   // 添加到延迟队列中去
        }    public void start() {
            scheduler.start();  // 启动任务调度器
        }    public void stop() {
            scheduler.stop();  // 停止任务调度器
        }    private void execute() throws InterruptedException {
            submit(take());
        }    /**
         * <p>将任务提交给线程池去执行</p>
         *
         * @param task
         */
        private void submit(Runnable task) {
            executor.submit(task);
        }    /**
         * <p>强制停止工作</p>
         */
        private void shutdown() {
            executor.shutdown();
        }    /**
         * <p>获取到时间的任务,如果该任务下一次还需要执行,将该任务加回队列中去。</p>
         *
         * @return
         * @throws InterruptedException
         */
        private JobDelayed take() throws InterruptedException {
            JobDelayed jobDelayed = jobs.take();
            if(jobDelayed.hasNext()) {
                addJob(jobDelayed);
            }
            return jobDelayed;
        }    /**
         * <p>调度器</p>
         * 2010-5-28 下午11:40:58
         */
        private static class Scheduler implements Runnable {        private SchedulerManager manager;
            private boolean running = false;        /**
             * 使用调度管理器构造
             * @param manager
             */
            public Scheduler(SchedulerManager manager) {
                this.manager = manager;
            }        /**
             * <p>启动该调度器</p>
             */
            public void start() {
                if(!running) {
                    manager.submit(this);
                    this.running = true;
                }
            }        /**
             * 执行任务调度工作
             */
            @Override
            public void run() {
                while(running) {
                    try {
                        manager.execute();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }        /**
             * <p>强制停止该调度器</p>
             */
            public void stop() {
                manager.shutdown();
                running = false;
            }
        }
    }/**
     * <p>需要进行任务调度的工作内容</p>
     */
    interface Job {
        public void execute();
    }/**
     * <p>测试工作,输出当前时间</p>
     */
    class MyJob implements Job {
        public void execute() {
            System.out.printf("JOB OUTPUT: %tF %<tT%n", System.currentTimeMillis());
        }
    }/**
     * <p>需要进行调度工作的任务</p>
     */
    interface JobDelayed extends Delayed, Runnable {    /**
         * <p>计算下一次执行的时间</p>
         */
        public void nextTime();    /**
         * <p>下一次是否需要执行</p>
         */
        public boolean hasNext();
    }/**
     * <p>需要进行每分钟调度工作的任务</p>
     */
    class EveryMinuteDelay implements JobDelayed {    private long nextTime;
        private Job job;    public EveryMinuteDelay(Job job) {
            this.job = job;
        }    public void nextTime() {
            Calendar c = Calendar.getInstance();
            c.set(Calendar.SECOND, 0);
            c.set(Calendar.MILLISECOND, 0);
            c.add(Calendar.MINUTE, 1);
            this.nextTime = c.getTimeInMillis();  // 这个任务的 nextTime 为下一分钟
        }    public boolean hasNext() {
            return true;   // 永远执行下去
        }    @Override
        public long getDelay(TimeUnit unit) {
            return nextTime - System.currentTimeMillis();   // 是否超时
        }    @Override
        public int compareTo(Delayed o) {
            return (int)(o.getDelay(TimeUnit.MILLISECONDS) - getDelay(TimeUnit.MILLISECONDS));
        }    @Override
        public void run() {
            job.execute();   // 执行任务
        }    public String toString() {
            return String.format("next: %tF %<tT", nextTime);
        }
    }
      

  15.   

    quart 本来就是独立的项目。spring 只是plugin 它而已。quart自己就提供了servlet的 plugin。如楼上所示,自己单独启动quart,技术这个东西分清拎清也十分重要。
      

  16.   


    搞那么复杂干嘛?其实你这问题挺简单的,不要想得太复杂了:思路:就使用java 的Timmer类,就可以搞定了。给你个例子
    /**
     * @author troy(J2EE)
     * @version 1.0
     */
    import java.util.Timer;
    import java.util.TimerTask;
    public class Test {   
        private final Timer timer = new Timer();
    private final static long DELAY_TIME=2 * 1000;//任务延迟时间:单位毫秒
    private final static long PERIO_TIME=2 * 1000;//任务运行周期: 单位毫秒
        public void start() { 
           timer.schedule(new SendMsgTask(), DELAY_TIME,PERIO_TIME);
        } 
       public static void main(String[] args) { 
           Test test = new Test(); 
           test.start();
        }
    }
    class SendMsgTask extends TimerTask{
    private static int i=0;
    public void run() { 
    sendMsg();

    private void sendMsg() {
    i++;
    System.out.println("发送短信 -- 开始 (第"+i+"次)");

    }
      

  17.   

    思路:

    任务执行时,先延迟一定时间,刚好到第二天早晨的8点时,任务开始执行; 任务运行周期为 :24 小时(每天)
    DELAY_TIME 这个参数: 是延迟时间,你可以new Date()获取当前时间,取到后跟 8点进行比对,设置好延迟时间这个参数;PERIO_TIME 这个参数: 是任务运行周期,你这种情况的话 应该设置为:24*60*60*1000备注:考虑问题要严谨,有几个问题要注意:1)何时关闭 计时器?2)任务执行失败了 怎么处理? 3)是否要配个日志?……
      

  18.   

    再发一个注释多一点的改进版本,短信发送5次后 自动停止 /**
     * @author troy(J2EE)
     * @version 1.0
     */
    import java.util.Timer;
    import java.util.TimerTask;
    public class Test {   
        private final static Timer timer = new Timer();
    public final static Timer getTimer(){
    return timer;//获取timer对象的实例
    }
    private final static long DELAY_TIME=2 * 1000;//任务延迟时间:单位毫秒
    private final static long PERIO_TIME=2 * 1000;//任务运行周期: 单位毫秒
        public void start() { 
           timer.schedule(new SendMsgTask(),DELAY_TIME,PERIO_TIME);//设置定时任务
        } 
       public static void main(String[] args) { 
           Test test = new Test(); 
           test.start();//开启任务
        }
    }
    class SendMsgTask extends TimerTask{
    private static int i=0;
    public void run() { 
    sendMsg();

    private void sendMsg() {
    i++;
    System.out.println("发送短信 -- 开始 (第"+i+"次)");
    if(i==5){
    Test.getTimer().cancel();//当发送5次后停止--计时器
    }

    }
    程序运行结果:---------- java1.5 -- 运行 ----------发送短信 -- 开始 (第1次)
    发送短信 -- 开始 (第2次)
    发送短信 -- 开始 (第3次)
    发送短信 -- 开始 (第4次)
    发送短信 -- 开始 (第5次)输出完毕 (耗时 10 秒) - 正常终止

      

  19.   

    我觉得
    既然相隔的周期不相同。就不要使用timer.scheduleAtFixedRate(timerTask, date, period);
    改用只执行一次的schedule(TimerTask task, long delay);
    然后每次执行后,计算出下一次执行所需的间隔。
    这样就简单多了。
      

  20.   

    linux crontab定时执行么
    也不需要什么框架
      

  21.   

     Quartz  就多加一个jar包而已,改动不大!