在Java 8中使用LocalTime阻止当前时间在给定时间之前60秒?

时间:2016-11-19 13:46:39

标签: date time java-8 blocking

我想就解决问题的最佳方法提出一些建议。

我希望我的程序在给定时间之前的当前时间为60秒时阻止,在Java 8中使用LocalTime?

所以它会是这样的:

LocalTime time1 = LocalTime.of(13, 11)
LocalTime currentTime = LocalTime.now()

然后一些代码实现了一些逻辑,如:Thread.sleep(直到currentTime< time1 - 60秒)

任何帮助都会很棒,谢谢!

2 个答案:

答案 0 :(得分:3)

使用LocalTime minusSeconds方法将时间调整为60秒(或使用minusMinutes)。然后使用Duration.between获取两次之间的持续时间:

LocalTime time1 = LocalTime.of(13, 11);

LocalTime untilTime = time1.minusSeconds(60);

LocalTime currentTime = LocalTime.now();

Duration duration = Duration.between(currentTime, untilTime);

// TODO possibly check duration.isNegative()

Thread.sleep(duration.toMillis());

答案 1 :(得分:0)

好吧,将LocalTime转换为LocalTime,差异为60秒,这是微不足道的。但是,虽然很容易计算到LocalTime.now()的差异以获得等待的时间,但是在计算差异时存在时间流逝的问题,因此当您调用wait函数时该值已经不准确。

虽然当你在多任务系统中等待时总的来说不精确,即在等待之后会有任意执行速度和线程调度,你应该避免另外提高它

更好的解决方案是计算截止日期,即使它可能看起来稍微复杂一点,并等待到达截止日期:

LocalTime target = LocalTime.of(12, 50).minusSeconds(60);
long deadLine = target.atDate(LocalDate.now()).atZone(ZoneId.systemDefault())
                      .toInstant().toEpochMilli();
while(System.currentTimeMillis() < deadLine) {
    // in case you want to support interruption:
    if(Thread.interrupted())
        throw new InterruptedException();
    LockSupport.parkUntil(target, deadLine);
}

此代码允许您决定是否支持中断。请注意,即使您不支持它,仍然需要循环来正确处理所谓的虚假唤醒。但是,虽然循环的条件检查和parkUntil调用之间会有经过的时间,但由于截止日期的性质,它将被处理,即如果已达到截止日期,parkUntil将立即返回 - 之间。

第一个参数是可选的,即您也可以调用parkUntil(deadLine)。它提供了有关线程等待原因的调试提示,例如当指定了参数时,线程转储将如下所示:

"main" #1 prio=5 os_prio=0 tid=0x0000000002b20800 nid=0x2aa8 waiting on condition [0x0000000002a2f000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000076b007220> (a java.time.LocalTime)
    at java.util.concurrent.locks.LockSupport.parkUntil(LockSupport.java:256)
    …

显示正在发生的事情。此外,如果等待持续时间足够长,另一个线程可以调用getBlocker并检查返回的对象。