java 每天3点到4点每隔5分钟执行一次
我之前写了一个是每天3点执行
现在需求是每天3点开始,每隔5分钟执行一次,到4点截止,请问怎么改?
下面是我已经实现的每天3点定时任务代码:
public class TimerManager {
//时间间隔
private static final long PERIOD_DAY = 24 * 60 * 60 * 1000;
public TimerManager() {
Calendar calendar = Calendar.getInstance();
/*** 定制每日15:00执行方法 ***/
calendar.set(Calendar.HOUR_OF_DAY,15);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Date date=calendar.getTime(); //第一次执行定时任务的时间
//如果第一次执行定时任务的时间 小于 当前的时间
//此时要在 第一次执行定时任务的时间 加一天,以便此任务在下个时间点执行。如果不加一天,任务会立即执行。
if (date.before(new Date())) {
date = this.addDay(date, 1);
}
Timer timer = new Timer();
CommonTimerTask task = new CommonTimerTask();
//安排指定的任务在指定的时间开始进行重复的固定延迟执行。
timer.schedule(task,date,PERIOD_DAY);
}
// 增加或减少天数
public Date addDay(Date date, int num) {
Calendar startDT = Calendar.getInstance();
startDT.setTime(date);
startDT.add(Calendar.DAY_OF_MONTH, num);
return startDT.getTime();
}
}
[解决办法]
思路 取hour ==3开始 过5分钟执行下方法,hour ==4时结束
[解决办法]
定时器
public class test extends TimerTask { @Override public void run() { System.out.println("asdsdasd"); Timer timer = new Timer() ; timer.schedule(new test(), new Date(System.currentTimeMillis()+2000)) ; } public static void main(String[] args) throws Exception { Timer timer = new Timer() ; timer.schedule(new test(), new Date(System.currentTimeMillis()+10000)) ;}
[解决办法]
package referer.test.csdn;import java.util.Calendar;import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class Test { public static void main(String[] args) { new Test(); } private Timer t = new Timer(); private class MyTask extends TimerTask { @Override public void run() { Calendar c = Calendar.getInstance(); // 处理该处理的程序 System.out.println("当前时间:" + c.getTime()); // 如果超过4点了就不执行了 if (c.get(Calendar.HOUR_OF_DAY) >= 4) { return; } // 否则定时5分钟之后继续 c.set(Calendar.MINUTE, c.get(Calendar.MINUTE) + 5); t.schedule(new MyTask(), c.getTime()); } } public Test() { t.schedule(new MyTask(), getTime(3), 1000 * 60 * 60 * 24); } // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); /** * 获取当天之后1天的开始时间 */ private Date getTime(int beginHour) { Calendar c = Calendar.getInstance(); c.set(Calendar.DATE, c.get(Calendar.DATE) + 1); c.set(Calendar.HOUR_OF_DAY, beginHour); c.clear(Calendar.MINUTE); c.clear(Calendar.SECOND); return c.getTime(); }}
[解决办法]
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); }}