加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java每月计时器

发布时间:2020-12-15 05:05:18 所属栏目:Java 来源:网络整理
导读:我正在尝试创建一个Timer / TimerTask,它将在每个月的同一天运行.我无法安排重复计时器,因为一个月不会总是相同的时间长度. 所以,这是我的解决方案: public class MyTask extends TimerTask { public void run(){ //do process file stuff if(scheduledExec
我正在尝试创建一个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完成后,是否会通过垃圾回收来处理该线程和对象?随着时间的推移,我不想建立一堆没有做任何事情但没有被删除的线程.也许我对Threads和Timers的运作方式没有正确的理解……

只要我不必使用第三方JAR,我就可以建议其他方法来创建月度计时器.

谢谢!

解决方法

如果你担心的是创建不需要的对象,你总是可以创建一个对象,然后创建/“销毁”所有引用,因此创建的对象可能是gc’ed.

在最坏的情况下,一年内你将有12个不需要的物品,我认为这是可以忍受的.你的担忧仍然有效.

这是我在执行结束后跟随Joel建议的计划.注意,当前的Timer被一个新的替换,因此,定时器和定时器任务都可以是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,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();

    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读