Java 定时器 每月一号 8点执行 如何写呢?

fsolsh 2010-05-27 10:41:10
短信发送平台,需要实现一个定时器,每个月1号早8点给特定人群发送短信
timer.scheduleAtFixedRate(timerTask, date, period);
第三个参数该怎么设?毕竟每个月的1号对应第三个参数不是固定值?
...全文
3749 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
angle006 2010-09-07
  • 打赏
  • 举报
回复
定时器的周期设定为天,每天的8点跑下定时器,判断今天是不是一号就可以了,如果是一号就执行短信发送,如果不是一号就什么也不做
qingmumu1985 2010-09-07
  • 打赏
  • 举报
回复
mark,等下回来学习!
yaoweijq 2010-09-07
  • 打赏
  • 举报
回复
linux crontab定时执行么
也不需要什么框架
e9876 2010-09-07
  • 打赏
  • 举报
回复
我觉得
既然相隔的周期不相同。就不要使用timer.scheduleAtFixedRate(timerTask, date, period);
改用只执行一次的schedule(TimerTask task, long delay);
然后每次执行后,计算出下一次执行所需的间隔。
这样就简单多了。
uastation 2010-09-07
  • 打赏
  • 举报
回复
不知楼主解决没?解决了的话,可否把解决之道共享出来?
zhongwuxin 2010-09-07
  • 打赏
  • 举报
回复
Quartz 就多加一个jar包而已,改动不大!
xianaofei 2010-09-07
  • 打赏
  • 举报
回复
在事件监听器的方法里写逻辑判断啊
宁静-夏天 2010-05-29
  • 打赏
  • 举报
回复
quart 本来就是独立的项目。

spring 只是plugin 它而已。

quart自己就提供了servlet的 plugin。

如楼上所示,自己单独启动quart,技术这个东西分清拎清也十分重要。

  • 打赏
  • 举报
回复
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);
}
}




Thinking_In_IT 2010-05-29
  • 打赏
  • 举报
回复
再发一个注释多一点的改进版本,短信发送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 秒) - 正常终止



狂屠 2010-05-29
  • 打赏
  • 举报
回复
上面的写的完全看不懂,还得继续学习啊
Thinking_In_IT 2010-05-29
  • 打赏
  • 举报
回复
思路:

任务执行时,先延迟一定时间,刚好到第二天早晨的8点时,任务开始执行; 任务运行周期为 :24 小时(每

天)


DELAY_TIME 这个参数: 是延迟时间,你可以new Date()获取当前时间,取到后跟 8点进行比对,设置好

延迟时间这个参数;

PERIO_TIME 这个参数: 是任务运行周期,你这种情况的话 应该设置为:24*60*60*1000

备注:

考虑问题要严谨,有几个问题要注意:

1)何时关闭 计时器?

2)任务执行失败了 怎么处理?

3)是否要配个日志?

……
Thinking_In_IT 2010-05-29
  • 打赏
  • 举报
回复
[Quote=引用楼主 fsolsh 的回复:]
短信发送平台,需要实现一个定时器,每个月1号早8点给特定人群发送短信
timer.scheduleAtFixedRate(timerTask, date, period);
第三个参数该怎么设?毕竟每个月的1号对应第三个参数不是固定值?
[/Quote]

搞那么复杂干嘛?其实你这问题挺简单的,不要想得太复杂了:

思路:

就使用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+"次)");
}
}

zhanglongnihao 2010-05-29
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 bao110908 的回复:]
Java 里面要实现这样的定时任务还有比较麻烦的,不建议自己去实现,把 Quartz 这个框架的 jar 加进来吧。对于你的这个用途,只用 Quartz 就可以了,不需要用什么 Spring 集成的。

如果需要自己实的话,可以使用 java.util.concurrent.DelayQueue,这个称为延迟队列,是 Java 集合框架的实现之一。存放进去的对象必须实现 java.util.c……
[/Quote]
这个不错,学习啦
SIOSXIAOQIANG 2010-05-29
  • 打赏
  • 举报
回复
先收藏了,在看,现在加班。。。
CrazyPastor 2010-05-28
  • 打赏
  • 举报
回复
Thread.sleep线和里.在学校的时候也作过一个.用毫秒弄的定时关机.这个应该会有用
zcywell 2010-05-28
  • 打赏
  • 举报
回复
顶一下
长公子冰 2010-05-28
  • 打赏
  • 举报
回复
我们的是每天要执行,楼主这个周期性太长了,所以还是建议使用框架吧。
shine333 2010-05-28
  • 打赏
  • 举报
回复
我一般都建议对超过1周以上的定期任务,使用操作系统的任务。以免正好期间有服务器维护、宕机或者其他情况
shine333 2010-05-28
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 icewee 的回复:]

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

睡美人
加载更多回复(17)

67,516

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧