Java 每月定时器
我正在尝试创建一个将在每个月的同一天运行的计时器/计时器任务。我无法安排重复计时器,因为一个月的时间长度并不总是相同。
所以,这是我的解决方案:
public class MyTask extends TimerTask {
public void run(){
//do process file stuff
if(scheduledExecutionTime() != 0){
TimerHelper.restartMyTimer();
}
}
}
public class TimerHelper {
public static HashTable timersTable = new HashTable();
public static void restartMyTimer(){
Calendar runDate = Calendar.getInstance();
runDate.set(Calendar.DAY_OF_MONTH, 1);
runDate.set(Calendar.HOUR_OF_DAY, 4);
runDate.set(Calendar.MINUTE, 0);
runDate.add(Calendar.MONTH, 1);//set to next month
MyTask myTask = new MyTask();
Timer myTimer = new Timer();
myTimer.schedule(myTask, runDate.getTime());
timersTable = new HashTable();//keeping a reference to the timer so we
timersTable.put("1", myTimer);//have the option to cancel it later
}
}
我想我会遇到的问题是,因为第一个 TimerTask 创建了第二个 Timer,第一个 Timer 会因为创建了第二个 Timer 而被保留吗?在第一个计时器上的代码完成后,垃圾收集会处理该线程和对象吗?随着时间的推移,我不想建立一堆不做任何事情但又没有被删除的线程。也许我对线程和计时器的工作原理没有正确的理解...
只要我不必使用第三方 JAR,我就可以接受其他创建每月计时器的方法的建议。
谢谢!
I am trying to create a Timer/TimerTask that will run the same day of every month. I can't schedule a repeating Timer because a month won't always be the same lenght of time.
So, here is my solution:
public class MyTask extends TimerTask {
public void run(){
//do process file stuff
if(scheduledExecutionTime() != 0){
TimerHelper.restartMyTimer();
}
}
}
public class TimerHelper {
public static HashTable timersTable = new HashTable();
public static void restartMyTimer(){
Calendar runDate = Calendar.getInstance();
runDate.set(Calendar.DAY_OF_MONTH, 1);
runDate.set(Calendar.HOUR_OF_DAY, 4);
runDate.set(Calendar.MINUTE, 0);
runDate.add(Calendar.MONTH, 1);//set to next month
MyTask myTask = new MyTask();
Timer myTimer = new Timer();
myTimer.schedule(myTask, runDate.getTime());
timersTable = new HashTable();//keeping a reference to the timer so we
timersTable.put("1", myTimer);//have the option to cancel it later
}
}
The problem I think I'm going to run into is that because the first TimerTask creates the second Timer, will the first Timer be kept around because it created the second? After the code finishes on the first Timer, will that thread and object be taken care of by garbage collection? Over time I don't want to build up a bunch of Threads that aren't doing anything but aren't being removed. Maybe I don't have a proper understanding of how Threads and Timers work...
I'm open to suggestions of other ways to create a monthly timer as long as I don't have to use third party JARs.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
只使用计划的计时器怎么样,当您完成当前计划的任务计划时,下一步:
您可以使用 JodaTime 更容易地进行日期计算。
What about just using a scheduled timer, and as you complete the currently scheduled task schedule the next:
You can use JodaTime to do the date calculations more easily.
最简单的解决方案可能是使用 cron 或等效的方法来安排独立程序的执行...
the simplest solution might be to use cron or equivalent to schedule a stand-alone program execution...
Quartz 调度程序 库允许您根据 cron 作业表达式进行调度。
The Quartz scheduler library allows you to schedule based on cron job expressions.
我认为您还可以创建一个线程并从 DelayQueue 来执行此操作。但它并不像 ScheduledExecutorService 那么容易。
I think you could also create one single thread and read from DelayQueue to do this. But it's not as easy as ScheduledExecutorService.
为什么每次都需要重新创建Timer?计时器只是带有粘合代码的线程。取消它会导致该计时器上运行的其他任务终止。
最好使用以下内容:
TimerTaskWithCallback 仅在原始任务执行后执行 MonthlyTimer.taskCallback。可以有“try { } catch {} finally {}”粘合代码。
Why do you need to recreate Timer every time? Timer is just thread with glue code around. Cancelling it cause terminating of other tasks running on that Timer.
It is better to use the following:
TimerTaskWithCallback just executes MonthlyTimer.taskCallback after original task execution. Could have "try { } catch {} finally {}" glue code.
如果您担心创建不需要的对象,您始终可以创建一个对象,该对象又创建/“销毁”所有引用,因此创建的对象可能会被GC。
最坏的情况是,一年内你会拥有 12 个不需要的物品,我认为这是可以忍受的。不过你的担心还是有道理的。
这是我在执行结束时遵循乔尔建议的时间表的尝试。请注意,当前的计时器已被新的计时器替换,因此计时器和计时器任务都可以被GC。
If what worries you is to create unneeded objects you can alway create an object which in turn creates/"destroy" all the references, so the objects created may be gc'ed.
In the worst case, you'll have 12 unneeded objects in a year, which, I think is bearable. Still your concern is valid.
Here's my attempt following Joel's suggestion of schedule at the end of the execution. Notice, the current Timer is replaced by a new one, so, both, the timer and the timer task could be gc'ed.
我建议简单地使用 Quartz 并通过 Quartz 调度作业。 quartz-scheduler.org/docs/tutorials/crontrigger.html" rel="noreferrer">CronTrigger 允许您指定希望在每月的第一天执行作业,并让 Quartz处理时序逻辑。
这里是如何使用 CronTrigger 的进一步代码示例。
Quartz 是一个极其简单易用的库。
I would suggest simply using Quartz and scheduling jobs via a CronTrigger which will allow you to specify you want the job executed on the first day-of-the-month, and let Quartz handle the timing logic.
Here is a further code example of how to use CronTrigger.
Quartz is a dead-simple easy library to use.