我想就解决问题的最佳方法提出一些建议。
我希望我的程序在给定时间之前的当前时间为60秒时阻止,在Java 8中使用LocalTime?
所以它会是这样的:
LocalTime time1 = LocalTime.of(13, 11)
LocalTime currentTime = LocalTime.now()
然后一些代码实现了一些逻辑,如:Thread.sleep(直到currentTime< time1 - 60秒)
任何帮助都会很棒,谢谢!
答案 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
并检查返回的对象。