Java中是否有一种方法可以根据日期/小时制作事件监听器 例如,像在每个星期三的15.30运行此代码块,还是在11月15日的17.30运行此代码块?
答案 0 :(得分:3)
ScheduledExecutorService
对于您的两个问题,ScheduledExecutorService
是解决方案。了解Java内置的Executors framework,使多线程工作变得更加轻松和可靠。
此代码块在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偏移量为零小时-分钟-秒)。
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 )
如果要跟踪该任务的完成,请捕获该ScheduledFuture
调用返回的schedule
对象。
在每个星期三的15.30运行此代码块
使用与上面类似的代码。在每个任务运行结束时,计算等待下一次运行的时间,然后再次致电scheduledExecutorService.schedule
。因此,任务的一部分工作是安排其下一次运行。
如果要在特定时区看到的每天和每周的某天严格遵守时间表,则必须遵循上述方法。政客通常会更改其辖区使用的UTC补偿,因此时间长度会有所不同。因此,我们不能将每周任务安排为7天* 24小时* 60分钟* 60秒。星期长短不一,因此我们必须每次重新计算长度。
如果您确实想以完全相同的时间间隔重复运行,因此不必担心本地时钟的变化,请使用ScheduledExecutorService.scheduleAtFixedRate
或ScheduledExecutorService.scheduleWithFixedDelay
。这些已在Stack Overflow上讨论过很多次,因此请搜索以了解更多信息。