在java中每个月调用x函数

时间:2014-09-28 11:36:43

标签: java scheduler

每个月我都想用Java运行某个任务。但是,我无法在此计算机上访问cron系统或Java环境之外的任何内容。

实施此类系统的最有效方法是什么,或者是否存在某人可以为我提供链接的系统?我会将当前时间存储在文件中,然后像每天一样,比较它以查看差异是否为一个月,如果是,则运行并重置。但这不是最准确的方法。

3 个答案:

答案 0 :(得分:3)

编写一个小程序,让操作系统处理每月执行。在Windows下使用task scheduler或在Linux下使用cronjob

答案 1 :(得分:0)

有几种选择:

  1. 手动完成。
  2. 设置cron调度程序。
  3. 如果你坚持使用纯Java Quartz scheduler

答案 2 :(得分:0)

执行者

现代Java包含出色的 Executor 框架,可轻松安排在后台线程上完成的工作。参见Tutorial。特别是,您需要ScheduledExecutorService

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool( 1 ) ;

要求该调度程序在经过一定时间后运行Runnable任务。

scheduler.schedule( runnable , delay , timeUnit ) ;  

java.time

因此,接下来您需要确定需要经过的时间。

定义您的目标,即每月的某天。 ThreeTen-Extra库为此提供了一个类DayOfMonth

DayOfMonth domTarget = DayOfMonth.of( 15 ) ;

获取要查看日历的时区中所显示的当前时刻。请记住,在任何给定时刻,日期随时区变化在全球各地。在东京的日期可能是“明天”,而在蒙特利尔的日期可能是“昨天”。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;

获取今天的月份。

DayOfMonth domToday = DayOfMonth.from( now ) ;

提取当前日期,仅提取日期,没有日期和时区。

LocalDate today = now.toLocalDate() ;

比较今天和目标之间的每月日期。如果今天已超过目标,请移至下个月。

LocalDate target = domTarget.atYearMonth( YearMonth.of( today ) ) ; // Get the date for our target day-of-month in the current month (current year-month). 
if( ! target.IsAfter( today ) ) {
    target = target.plusMonths( 1 ) ;  // If target is not after today, move to the next month.
}

获取目标日期的第一天。不要以为一天从00:00开始。在某些区域中的某些日期,一天可能会在其他时间开始,例如01:00。

ZonedDateTime start = target.atStartOfDay( z ) ;  // Determine the first moment of the day on that date in that zone.

现在,我们可以确定从现在到我们要运行任务的开始时间之间的经过时间。将此未附加到时间轴的时间跨度表示为Duration。在内部,此类是整个秒的计数加上分数的秒。

Duration d = Duration.between( now , start ) ;  // Calculate elapsed time.

最后,我们可以告诉调度程序一段时间。我们使用TimeUnit枚举指定粒度。

scheduler.schedule( runnable , d.toSeconds() , TimeUnit.SECONDS ) ;  // Tell our ScheduledExecutorService to run some code after the specified time to wait.

请确保在您的应用结束时正常关闭执行程序服务,否则其线程可能会在您的应用结束后继续运行。

注意:我未经测试就将这段代码写在了头上。因此,它可能并不完美,但应该使您朝正确的方向前进。