执行者
老式方法使用Timer 类。
New-school 方式使用Executors framework 处理后台线程上调度任务的细节。
设置一个执行程序以每隔几个小时运行一次Runnable。该任务检查当前时刻。如果当前日期的星期几是星期一,并且您的文件尚未写入,请写入。如果没有,则让 Runnable 过期。 scheduled executor service 将在几个小时后再次运行,并一次又一次地重复。
第一步是获取当前日期。
时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因区域而异。例如,Paris France 中午夜后几分钟是新的一天,而 Montréal Québec 中仍然是“昨天”。
如果没有指定时区,JVM 会隐式应用其当前的默认时区。该默认值可能在运行时(!)期间change at any moment,因此您的结果可能会有所不同。最好将 desired/expected time zone 明确指定为参数。
以continent/region 的格式指定proper time zone name,例如America/Montreal、Africa/Casablanca 或Pacific/Auckland。切勿使用 2-4 个字母的缩写,例如 EST 或 IST,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z );
从中获取当前星期几。
DayOfWeek dow = today.getDayOfWeek() ;
如果今天是星期一,则查看文件是否已写入。如果没有,就写吧。
if( dow.equals( DayOfWeek.MONDAY ) ) {
if( file not written ) { write file }
}
将所有内容放在一个命名方法中。
private void writeFileOnMonday ( ) {
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
DayOfWeek dow = today.getDayOfWeek();
if ( dow.equals( DayOfWeek.MONDAY ) ) {
if ( file not written ){ write file }
}
}
利用scheduled executor service 中的工作负载。指定运行之间要等待的小时数。如果我们指定每 3 小时运行一次任务,那么根据逻辑,我们的每周文件将在每个星期一的午夜和凌晨 3 点之间的某个时间写入。
计划执行器服务的一大问题:如果在任何运行中,您的任务抛出了Throwable(Exception 或Error)并到达执行器,重复的任务执行就会静默停止。因此,请始终将您的任务包装在 try-catch 中。见this Question。
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); // Convenience method to produce an executor service.
ScheduledFuture scheduledFuture = // A handle to check the status of your task. May or may not be useful to you.
scheduledExecutorService
.scheduleWithFixedDelay( new Runnable() { // Implement the `Runnable` interface as your task.
@Override
public void run ( ) {
try {
writeFileOnMonday();
} catch (Exception e ) {
… handle unexected exception
}
}
} ,
0 , // Initial delay
3 , // Delay between runs.
TimeUnit.HOURS ); // Unit of time meant for the pair of delay numbers above.
搜索 Stack Overflow 以获取更多信息,因为所有这些内容已经被多次介绍过。
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可能会在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。