让线程休眠到设定的日期?

gz5pxeao  于 2021-07-12  发布在  Java
关注(0)|答案(2)|浏览(257)

我想知道如何让线程休眠到一个设定日期,例如设定日期14/feb/2020。
线程在此日期之前将保持休眠状态。在java中有什么方法可以做到这一点吗?。

wfsdck30

wfsdck301#

执行人服务

定义 Runnable (或 Callable ). 这意味着只要有一个 run 方法以符合接口的合同。
在lambda语法中:

Runnable runnable =
    () -> { 
        System.out.println( "Looking up fresh stock prices at " + Instant.now().toString() ) ; 
    } 
;

接下来,研究嵌入到现代java中的executors框架。请参见oracle教程。这个框架大大简化了在线程上调度工作的复杂工作。
具体来说,你想用 ScheduledExecutorService . 此接口用于安排任务在特定时间运行一次(实际上,在特定延迟过期后运行一次),或重复运行任务。你当然想要前者。
Executors 班级。为了满足你的需要,我们只需要一根线。在其他情况下,可能需要使用线程池。

ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor() ;

指定任务执行前等待的时间(延迟)。计算等待所需的时间。
指定目标日期。在实际工作中,我会证实这个日期确实是在未来。

LocalDate localDate = LocalDate.of( 2020 , Month.FEBRUARY , 23 ) ;

我们需要一个特定的时刻,而不仅仅是一个约会。我想你会想要那天的第一刻。别以为现在是00:00。某些日期的某些区域中的某些天可能在另一个时间开始,例如01:00。总是让java.time决定第一个时刻。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = localDate.atStartOfDay( z ) ;

从该时区转换为utc。

Instant then = zdt.toInstant() ;

捕捉utc中的当前时刻。

Instant now = Instant.now() ;

将经过的时间计算为 Duration .

Duration d = Duration.between( now , then ) ;

现在安排任务在延迟过期后运行。我建议增加一点时间,确保所有相关系统的时钟都能很好地进入新的一天。加上午夜往往是计算的关键时刻,许多cron作业、日志滚动、实用程序和报告都在运行。也许再多加几分钟。

ses.scheduleWithFixedDelay( runnable , d.plusMinutes( 7 ).toMinutes() , TimeUnit.MINUTES);

您可以选择捕获返回的 ScheduledFuture 监视你的任务。
重要信息:当不再需要executor服务时,或者当您的应用程序正在关闭时,请务必优雅地关闭executor服务。否则,你的线程可能会继续在后台运行,在你的应用程序退出后幸存。

ses.shutdown() ;
4xrmg8kj

4xrmg8kj2#

可以使用system.currenttimemillis获取当前日期,获取给定日期的毫秒数(在本例中为2月14日),计算将当前日期与给定日期分开的毫秒数,并使用此值调用sleep()方法。老实说,我不知道这个的实际用途是什么。
下面是一个快速解决方案:

public static void main(String[] args) {
    long currentMillis = System.currentTimeMillis();
    long givenDateMillis = LocalDateTime.of(2020, 2, 14, 0, 0, 0)
            .atZone(ZoneId.systemDefault())
            .toInstant()
            .toEpochMilli();

    Thread.sleep(givenDateMillis - currentMillis);
}

我不建议在任何生产代码中使用它,对于这种情况,我建议使用某种调度器。

相关问题