bme*_*ing 3 java multithreading timer
我正在尝试创建一个Timer/TimerTask,它将在每个月的同一天运行.我无法安排重复计时器,因为一个月不会总是相同的时间长度.
所以,这是我的解决方案:
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
}
}
Run Code Online (Sandbox Code Playgroud)
我认为我将遇到的问题是因为第一个TimerTask创建了第二个Timer,第一个Timer会被保留,因为它创建了第二个吗?代码在第一个Timer完成后,是否会通过垃圾回收来处理该线程和对象?随着时间的推移,我不想建立一堆没有做任何事情但没有被删除的线程.也许我对Threads和Timers的运作方式没有正确的理解......
只要我不必使用第三方JAR,我就可以建议其他方法来创建月度计时器.
谢谢!
我建议只使用Quartz并通过CronTrigger调度作业,这将允许您指定您希望在第一天的月份执行作业,并让Quartz处理时序逻辑.
Quartz是一个简单易用的简单库.
如果您担心创建不需要的对象,您始终可以创建一个对象,该对象又创建/“销毁”所有引用,因此创建的对象可能会被GC。
最坏的情况是,一年内你会拥有 12 个不需要的物品,我认为这是可以忍受的。不过你的担心还是有道理的。
这是我在执行结束时遵循乔尔建议的时间表的尝试。请注意,当前的计时器已被新的计时器替换,因此计时器和计时器任务都可以被GC。
package monthly.schedule;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Date;
import java.util.Calendar;
public class MonthlyTimer {
// What to do
private final Runnable whatToDo;
// when
private final int dayOfMonth;
private final int hourOfDay;
// The current timer
private Timer current = new Timer();//to avoid NPE
public void cancelCurrent() {
current.cancel();// cancel this execution;
current.purge(); // removes the timertask so it can be gc'ed
}
// create a new instance
public static MonthlyTimer schedule( Runnable runnable, int dayOfMonth, int hourOfDay ) {
return new MonthlyTimer( runnable, dayOfMonth, hourOfDay );
}
private MonthlyTimer(Runnable runnable, int day, int hour ) {
this.whatToDo = runnable;
this.dayOfMonth = day;
this.hourOfDay = hour;
schedule();
}
// Schedules the task for execution on next month.
private void schedule() {
// Do you mean like this?
cancelCurrent();
current = new Timer(); // assigning a new instance
// will allow the previous Timer to be gc'ed
current.schedule( new TimerTask() {
public void run() {
try {
whatToDo.run();
} finally {
schedule();// schedule for the next month
}
}
} , nextDate() );
}
// Do the next date stuff
private Date nextDate() {
Calendar runDate = Calendar.getInstance();
runDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
runDate.set(Calendar.HOUR_OF_DAY, hourOfDay);
runDate.set(Calendar.MINUTE, 0);
runDate.add(Calendar.MONTH, 1);//set to next month
return runDate.getTime();
}
}
class UseIt {
public static void main( String [] args ) {
int the1st = 1;
int at16hrs = 16;
MonthlyTimer t = MonthlyTimer.schedule( new Runnable() {
public void run() {
System.out.println( "Hola" );
}}, the1st, at16hrs );
// will print "Hola" every 1st at 16:00 hrs.
// if needed you can cancel with:
t.cancelCurrent();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5976 次 |
| 最近记录: |