我想知道如何让线程休眠到一个设定日期,例如设定日期14/feb/2020。线程在此日期之前将保持休眠状态。在java中有什么方法可以做到这一点吗?。
wfsdck301#
定义 Runnable (或 Callable ). 这意味着只要有一个 run 方法以符合接口的合同。在lambda语法中:
Runnable
Callable
run
Runnable runnable = () -> { System.out.println( "Looking up fresh stock prices at " + Instant.now().toString() ) ; } ;
接下来,研究嵌入到现代java中的executors框架。请参见oracle教程。这个框架大大简化了在线程上调度工作的复杂工作。具体来说,你想用 ScheduledExecutorService . 此接口用于安排任务在特定时间运行一次(实际上,在特定延迟过期后运行一次),或重复运行任务。你当然想要前者。从 Executors 班级。为了满足你的需要,我们只需要一根线。在其他情况下,可能需要使用线程池。
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
Duration d = Duration.between( now , then ) ;
现在安排任务在延迟过期后运行。我建议增加一点时间,确保所有相关系统的时钟都能很好地进入新的一天。加上午夜往往是计算的关键时刻,许多cron作业、日志滚动、实用程序和报告都在运行。也许再多加几分钟。
ses.scheduleWithFixedDelay( runnable , d.plusMinutes( 7 ).toMinutes() , TimeUnit.MINUTES);
您可以选择捕获返回的 ScheduledFuture 监视你的任务。重要信息:当不再需要executor服务时,或者当您的应用程序正在关闭时,请务必优雅地关闭executor服务。否则,你的线程可能会继续在后台运行,在你的应用程序退出后幸存。
ScheduledFuture
ses.shutdown() ;
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); }
我不建议在任何生产代码中使用它,对于这种情况,我建议使用某种调度器。
2条答案
按热度按时间wfsdck301#
执行人服务
定义
Runnable
(或Callable
). 这意味着只要有一个run
方法以符合接口的合同。在lambda语法中:
接下来,研究嵌入到现代java中的executors框架。请参见oracle教程。这个框架大大简化了在线程上调度工作的复杂工作。
具体来说,你想用
ScheduledExecutorService
. 此接口用于安排任务在特定时间运行一次(实际上,在特定延迟过期后运行一次),或重复运行任务。你当然想要前者。从
Executors
班级。为了满足你的需要,我们只需要一根线。在其他情况下,可能需要使用线程池。指定任务执行前等待的时间(延迟)。计算等待所需的时间。
指定目标日期。在实际工作中,我会证实这个日期确实是在未来。
我们需要一个特定的时刻,而不仅仅是一个约会。我想你会想要那天的第一刻。别以为现在是00:00。某些日期的某些区域中的某些天可能在另一个时间开始,例如01:00。总是让java.time决定第一个时刻。
从该时区转换为utc。
捕捉utc中的当前时刻。
将经过的时间计算为
Duration
.现在安排任务在延迟过期后运行。我建议增加一点时间,确保所有相关系统的时钟都能很好地进入新的一天。加上午夜往往是计算的关键时刻,许多cron作业、日志滚动、实用程序和报告都在运行。也许再多加几分钟。
您可以选择捕获返回的
ScheduledFuture
监视你的任务。重要信息:当不再需要executor服务时,或者当您的应用程序正在关闭时,请务必优雅地关闭executor服务。否则,你的线程可能会继续在后台运行,在你的应用程序退出后幸存。
4xrmg8kj2#
可以使用system.currenttimemillis获取当前日期,获取给定日期的毫秒数(在本例中为2月14日),计算将当前日期与给定日期分开的毫秒数,并使用此值调用sleep()方法。老实说,我不知道这个的实际用途是什么。
下面是一个快速解决方案:
我不建议在任何生产代码中使用它,对于这种情况,我建议使用某种调度器。