Wait/sleep 直到 java 的特定时间(例如星期四 10:59)

Wait/sleep until a specific time (e.g. Thursday at 10:59) in java

我目前在网络机器人中使用 selenium 在网站上购买商品。当我搜索我想买的东西找不到时,我用driver.navigate().refresh()刷新页面看看现在有没有,它会一直这样做,直到它在发布时找到该产品页。但是,我希望在产品发布前几个小时启动我的机器人,该产品目前无法正常工作,因为在刷新页面大约 30 秒后,由于他们使用的反 ddos​​ 软件,我被禁止访问该页面。一种选择是增加刷新之间的延迟,但是我需要尽快赶上该产品的发布所以我试图找到一种方法让我的程序可以 wait/sleep 直到发布前 30 秒但是我正在努力寻找一种方法来做到这一点。

只需以适当的毫秒数调用 Thread.sleep

public static void main(String[] args) throws InterruptedException {
    long currentTime = System.currentTimeMillis();
    long releaseTime = currentTime + 1000 * 60 * 60 * 24 * 3; // 3 days

    Thread.sleep(releaseTime - currentTime);
}

另一种方法是使用 java.time classes:

public static void main(String[] args) throws InterruptedException {
    LocalDateTime now = LocalDateTime.now();
    LocalDateTime release = LocalDateTime.of(2019, 10, 30, 13, 30);

    long sleepDuration = Duration.between(now, release).toMillis();
    TimeUnit.MILLISECONDS.sleep(sleepDuration);
}

Java 9 介绍了 Duration class 的新方法,如 toSeconds()toMinutes() 等。

您也可以考虑使用 ScheduledExecutorService 来安排您的任务。如果您有多个任务要安排并且不希望为此阻塞多个线程,这将特别有用:

private static final ScheduledExecutorService service = new ScheduledThreadPoolExecutor(2);

private static ScheduledFuture<?> scheduleTask(Runnable task, LocalDateTime releaseTime) {
    Duration duration = Duration.between(LocalDateTime.now(), releaseTime);
    return service.schedule(task, duration.toSeconds(), TimeUnit.SECONDS);
}

一般来说,要睡到下周四 10:59,您可以使用以下代码:

LocalDateTime release = LocalDateTime.now()
            .with(TemporalAdjusters.nextOrSame(DayOfWeek.THURSDAY))
            .withHour(10)
            .withMinute(59);

Duration duration = Duration.between(LocalDateTime.now(), release);
TimeUnit.MILLISECONDS.sleep(duration.toMillis());

我认为与其休眠,不如看看 Spring 中带有 cron 表达式的计划任务...这样就不会出现阻塞的线程。

Scheduled Tasks with Spring
Cron Expressions