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

Java-使用wait()方法直到达到特定时间,java,multithreading,wait,Java,Multithreading,Wait,我有一个线程,它在程序的后台运行,并检测何时出现截止日期(由程序开始时的用户输入设置)。我在while循环中使用sleep(1000)方法实现了这一点 这一切都正常,但我想将它从使用sleep(1000)改为使用wait()和notifyAll()以与我的其余代码保持一致,并使警报实时发生,而不是延迟一秒钟直到线程重新唤醒 这是我目前拥有的 //Retrieve current date and time... Calendar now = Calendar.getInstanc

我有一个线程,它在程序的后台运行,并检测何时出现截止日期(由程序开始时的用户输入设置)。我在
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///
    ////////////////////////////
我试图将它改为使用
wait()
,但没有成功。有人能看到一种改变现有代码以实现我提到的方法的方法吗

提前感谢,,
马克

使用这个方法。

所以这个问题是,我如何使用
等待
来表现得像
睡眠
。如果要使用wait,则必须使用两个线程。使用a()

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

我们将使用现代框架()将最后期限设置为
x
分钟

接下来我们要安排一个任务,这样我们的线程将在x分钟内醒来

while(Instant.now().isBefore(deadline)){
    synchronized(deadline){    
        executor.schedule(
            ()->{
                synchronized(deadline){
                    deadline.notifyAll();
                }
            }, 
            Duration.between(Instant.now(),deadline).toMillis(), 
            TimeUnit.MILLISECONDS
        );
        deadline.wait();
    }
}
这是一个循环,以防出现虚假的觉醒。它重新提交任务,以防出现虚假的唤醒,同时另一个任务完成并且在线程再次调用wait之前没有唤醒线程

上面这句话有点开玩笑。真的,如果你只是使用下面的方法,它看起来更“实时”


来自oracle文档

使当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法,或者经过指定的时间

前提条件:当前线程必须拥有此对象的监视器

线程也可以在不被通知、中断或超时的情况下唤醒,即所谓的虚假唤醒。虽然这种情况在实践中很少发生,但应用程序必须通过测试本应导致线程被唤醒的条件来防范这种情况,并在条件不满足时继续等待。换句话说,等待应该总是在循环中发生,如下所示:

 synchronized (obj) {
     while (<condition does not hold>)
         obj.wait(timeout);
     ... // Perform action appropriate to condition
 }
synchronized(obj){
而()
对象等待(超时);
…//执行适合条件的操作
}

notifyAll在哪里被调用?为什么不按需要的秒数睡觉,而不是任意的1000秒呢?notifyAll()现在不会被调用,因为还没有wait()调用。现在它每秒钟检查一次,因为截止时间被输入为一分钟,而我只是每秒钟检查一次。我想改用wait()使其更精确@matt wait和sleep都使用操作系统来执行等待,其中一个并不比另一个更精确。事实上,等待不太准确,因为它可能会令人惊讶地醒来,而睡眠并不意味着你不应该忽略异常,除非你知道你可以安全地这样做。你不应该说错话;我不知道如何处理这个异常,所以我会假装它没有发生。Re,我想把它从使用sleep(1000)改为使用wait()和notifyAll()为什么
Thread.sleep(n)
o.wait(n)
用于解决不同的问题。您可以使用wait(n)代替sleep(n),但您唯一要做的就是混淆、骚扰和疏远其他试图阅读您的代码的程序员。原因是,程序员希望函数的名称能告诉他们一些您试图完成的事情。如果他们看到
wait(n)
,那么他们希望在某处找到
notify()
。但是如果他们看到
sleep(n)
他们知道不用费心去看。嗨,这个方法是怎么工作的?它会一直等到最后期限到来,然后退出while循环吗?@marcush它确实说明了它在javadoc中的作用。注意:这是用于使用锁的。如果你没有锁定一个对象,那么等待它是没有意义的。
while(Instant.now().isBefore(deadline)){
    synchronized(deadline){    
        executor.schedule(
            ()->{
                synchronized(deadline){
                    deadline.notifyAll();
                }
            }, 
            Duration.between(Instant.now(),deadline).toMillis(), 
            TimeUnit.MILLISECONDS
        );
        deadline.wait();
    }
}
long diff = deadline.getTimeInMillis()-now.getTimeInMillis();
if(diff>0)
    Thread.sleep(diff);
public final void wait(long timeout)
                throws InterruptedException
 synchronized (obj) {
     while (<condition does not hold>)
         obj.wait(timeout);
     ... // Perform action appropriate to condition
 }