在java中有没有一种方法可以使事件侦听器基于天/小时比如说,在每周三15.30运行这个代码块,或者在11月15日17.30运行这个码块?
ScheduledExecutorService
对于您的两个问题,ScheduledExecutorService
是解决方案。了解Java中内置的Executitors框架,使多线程工作更加简单可靠。
在特定日期/时间运行一次
此代码块于11月15日17:30
执行器服务可以在等待一定时间后运行任务。
首先确定跑步的时机。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.of( 2020 , 11 , 15 , 17 , 30 , 0 , 0 , z );
定义要运行的任务。
Runnable runnable = new Runnable()
{
@Override
public void run ( )
{
System.out.println( "Runnable running. " + ZonedDateTime.now( z ) );
}
};
获取由线程池支持的执行器服务。
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
计算从现在到任务需要运行的等待时间。在这里,我们使用Duration
类来计算经过的时间。我们传递的Instant
对象始终处于UTC(从UTC偏移0小时分秒(。
long delay = Duration.between( Instant.now() , zdt.toInstant() ).getSeconds(); // Calculate amount of time to wait until we run.
告诉执行器服务在等待该时间后运行该任务。请确保计算delay
长整数时使用的时间单位与TimeUnit
参数匹配。
scheduledExecutorService.schedule( runnable , delay , TimeUnit.SECONDS ); // ( Runnable , delay , TimeUnit of delay )
如果要跟踪该任务的完成情况,请捕获该schedule
调用返回的ScheduledFuture
对象。
重复运行
每周三15.30 运行此代码块
使用与上面看到的代码类似的代码。在每个任务的运行结束时,计算等待下一次运行的时间,然后再次调用scheduledExecutorService.schedule
。因此,任务的一部分工作是安排下一次运行。
如果你想在一天中的某个时间段和一周中的某一天坚持严格的时间表,就必须遵循刚才提到的方法。政客们经常更改其管辖区使用的UTC偏移量,因此天数各不相同。因此,我们不能将每周任务安排为7天*24小时*60分钟*60秒。周的长度各不相同,所以我们必须重新计算每次的长度。
如果您确实希望以完全相同的时间间隔重复运行,这样您就不关心本地的时钟变化,那么请使用ScheduledExecutorService.scheduleAtFixedRate
或ScheduledExecutorService.scheduleWithFixedDelay
。这些内容已经在Stack Overflow上介绍了很多次,所以请搜索以了解更多信息。