gpt4 book ai didi

Java 每月计时器

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:31:29 25 4
gpt4 key购买 nike

我正在尝试创建一个将在每个月的同一天运行的 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
}
}

我想我会遇到的问题是,因为第一个 TimerTask 创建了第二个 Timer,所以第一个 Timer 是否会因为它创建了第二个而保留下来?代码在第一个 Timer 上完成后,该线程和对象是否会被垃圾回收处理?随着时间的推移,我不想建立一堆什么都不做但不会被删除的线程。也许我对线程和定时器的工作原理没有正确的理解......

只要我不必使用第三方 JAR,我愿意接受有关创建每月计时器的其他方法的建议。

谢谢!

最佳答案

如果您担心创建不需要的对象,您总是可以创建一个对象,该对象又会创建/“销毁”所有引用,因此创建的对象可能会被 gc'ed。

在最坏的情况下,一年内您将有 12 个不需要的对象,我认为这是可以忍受的。你的担心仍然是有道理的。

这是我在执行结束时按照 Joel 的时间表建议进行的尝试。注意,当前的 Timer 被一个新的 Timer 替换了,所以,timer 和 timer task 都可以被 gc'ed。

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();

}
}

关于Java 每月计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4107011/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com