Java - 使用 wait() 方法直到达到特定时间

mar*_*thh 3 java multithreading wait

我有一个线程在我的程序后台运行并检测截止日期(由程序开始时的用户输入设置)何时发生。我已经在while循环中实现了这个并使用了该sleep(1000)方法。

一切正常,但我想将它从使用更改sleep(1000)为使用,wait()notifyAll()与我的其余代码保持一致,并使警报实时发生,而不是在线程之前滞后一秒重新醒来。

这是我目前拥有的

    //Retrieve current date and time...
    Calendar now = Calendar.getInstance();

    //deadline not yet reached
    while(now.before(deadline))
    {
        try
        {
            //wait a second and try again
            sleep(1000);
        }
        catch (InterruptedException intEx)
        {
            //Do nothing.
        }

        //Update current date and time...
        now = Calendar.getInstance();
        //run loop again
    }

    ////////////////////////////
    ///alert user of deadline///
    ////////////////////////////
Run Code Online (Sandbox Code Playgroud)

我试图将其更改为使用wait(),但没有成功。任何人都可以看到改变现有代码以实现我提到的方法的方法吗?

提前致谢,马克

mat*_*att 5

所以这个问题是,我怎样才能waitsleep. 如果要使用等待,则必须使用两个线程。使用ScheduledExecutorService教程)。

 ScheduledExecutorService executor = newSingleThreadScheduledExecutor();
Run Code Online (Sandbox Code Playgroud)

这可以完成一次并重复使用。否则,您必须关闭执行程序。

我们将x使用Instant现代java.time框架(教程)将截止日期设置为未来几分钟。

final Instant deadline = Instant.now().plus(x, ChronoUnit.MINUTES);
Run Code Online (Sandbox Code Playgroud)

接下来我们要安排一个任务,以便我们的线程将在 x 分钟内唤醒。

while(Instant.now().isBefore(deadline)){
    synchronized(deadline){    
        executor.schedule(
            ()->{
                synchronized(deadline){
                    deadline.notifyAll();
                }
            }, 
            Duration.between(Instant.now(),deadline).toMillis(), 
            TimeUnit.MILLISECONDS
        );
        deadline.wait();
    }
}
Run Code Online (Sandbox Code Playgroud)

它处于循环中,以防万一出现虚假唤醒。它重新提交任务,以防万一有一个虚假的唤醒,同时另一个任务完成并且在线程再次调用等待之前没有唤醒线程。

这上面是脸颊上的一点舌头。真的,如果您只使用以下内容,它看起来会更“实时”。

long diff = deadline.getTimeInMillis()-now.getTimeInMillis();
if(diff>0)
    Thread.sleep(diff);
Run Code Online (Sandbox Code Playgroud)