【问题标题】:Wait/sleep until a specific time (e.g. Thursday at 10:59) in java在java中等待/睡眠直到特定时间(例如星期四10:59)
【发布时间】:2019-10-21 16:53:26
【问题描述】:

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

【问题讨论】:

  • 你不能保持睡眠时间短,醒来后检查时间,如果时间很接近释放时间,你才提出请求?实际上,您可以从较长的睡眠时间开始,例如将剩余的时间少于 5 分钟左右,然后只有在接近时才缩短请求之间的睡眠时间。

标签: java time selenium-chromedriver wait


【解决方案1】:

只需使用适当的毫秒数调用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 类:

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 类引入了新方法,例如 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());

【讨论】:

  • 为什么不只是 while (release.isBefore(LocalDateTime.now())) { } 然后在那点之后进入例行程序?
  • @Bryan 因为那会忙着等待阻塞 CPU
  • @Bryan 这相当于问“我们到了吗?”在开车。
  • 他当前的机器人不断刷新,直到被禁止,但可以想象有相同的等待行为。
  • @Bryan 没有人说它不能,但我只是不认为这是一个好的解决方案。
【解决方案2】:

我认为你应该看看 Spring 中带有 cron 表达式的计划任务,而不是睡觉……这样你就不会有一个阻塞的线程坐在那里。

Scheduled Tasks with Spring
Cron Expressions

【讨论】:

  • 你确定你最后一句话是真的吗?我认为Scheduled 注释使用ScheduledExecutorService 使用DelayQueue,这仍然会导致线程阻塞。
  • 我不确定被阻塞的线程,但我很确定这是一个更干净的开发模式。
  • 当然,如果您已经在使用 Spring,那么这可能是更简洁的选择。但 OP 从未提及 Spring。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-27
  • 1970-01-01
  • 1970-01-01
  • 2010-10-13
  • 2016-09-03
相关资源
最近更新 更多