Java中是否有一个“直到条件变为真”的功能?

我正在为服务器编写侦听器线程,此刻我正在使用:


while (true){

    try {

        if (condition){

            //do something

            condition=false;

        }

        sleep(1000);


    } catch (InterruptedException ex){

        Logger.getLogger(server.class.getName()).log(Level.SEVERE, null, ex);

    }

}

使用上面的代码,我遇到了运行功能吃掉所有cpu时间循环的问题。睡眠功能有效,但似乎是临时解决方案,而不是解决方案。


是否有一些函数会阻塞直到变量“ condition”变为“ true”?还是连续循环等待变量值改变的标准方法?


慕哥9229398
浏览 518回答 3
3回答

慕村225694

这样的轮询绝对是最不受欢迎的解决方案。我假设您有另一个线程将做一些事情来使条件成立。有几种同步线程的方法。在您的情况下,最简单的方法是通过对象发出通知:主线程:synchronized(syncObject) {    try {        // Calling wait() will block this thread until another thread        // calls notify() on the object.        syncObject.wait();    } catch (InterruptedException e) {        // Happens if someone interrupts your thread.    }}其他线程:// Do something// If the condition is true, do the following:synchronized(syncObject) {    syncObject.notify();}syncObject本身可以很简单Object。

料青山看我应如是

EboMike的答案和Toby的答案都在正确的轨道上,但是它们都有致命的缺陷。该缺陷称为丢失通知。问题是,如果一个线程调用foo.notify(),它将根本不做任何事情,除非某个其他线程已经在foo.wait()调用中处于休眠状态。对象,foo不记得它已收到通知。有一个原因导致不允许您调用,foo.wait()或者foo.notify()除非线程在foo上同步。这是因为避免丢失通知的唯一方法是使用互斥量保护条件。完成后,它看起来像这样:使用者线程:try {    synchronized(foo) {        while(! conditionIsTrue()) {            foo.wait();        }        doSomethingThatRequiresConditionToBeTrue();    }} catch (InterruptedException e) {    handleInterruption();}生产者线程:synchronized(foo) {    doSomethingThatMakesConditionTrue();    foo.notify();}更改条件的代码和检查条件的代码都在同一对象上同步,并且使用者线程在等待之前显式测试条件。wait()当条件为真时,用户无法错过通知并永远陷入通话中。另请注意,这wait()是一个循环。这是因为,在一般情况下,当使用者重新获取foo锁并唤醒时,其他一些线程可能再次使条件变为假。即使您的程序无法做到这一点,在某些操作系统中,foo.wait()即使foo.notify()没有被调用,也可能返回。这被称为“ 伪唤醒”,它被允许发生,因为它使等待/通知在某些操作系统上更容易实现。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java