睡眠和检查,直到条件为真(Sleep and check until condition is tr

2019-07-18 13:47发布

有没有在Java库,它下面? 一个thread应反复sleep ,直到条件为真或达到最大时间x毫秒。

这种情况当测试等待一些条件,以成为真正的多发。 条件是由另一个影响thread

[编辑]只是为了更清楚,我想测试等待只有X毫秒它失败了。 它不能永远等待条件成为现实。 我加入一个人为的例子。

class StateHolder{
    boolean active = false;
    StateHolder(){
        new Thread(new Runnable(){
            public void run(){
                active = true;
            }
        }, "State-Changer").start()
    }
    boolean isActive(){
        return active;
    }
}


class StateHolderTest{
    @Test
    public void shouldTurnActive(){
        StateHolder holder = new StateHolder();
        assertTrue(holder.isActive); // i want this call not to fail 
    }
}

Answer 1:

编辑

大多数的答案注重与等待,并通知或条件(其中工作或多或少相同)的底层API:它是难以得到的权利,当你不使用它。 证明:这些答案2不正确使用等。
java.util.concurrent为您提供了高层次的API,所有这些复杂性已被隐藏。

恕我直言,有使用等待/通知模式没有点时,有一个内置在达到相同的concurrent包类。


甲CountDownLatch为1的初始计数正是如此:

  • 当条件为真,调用latch.countdown();
  • 在你等待的线程,使用: boolean ok = latch.await(1, TimeUnit.SECONDS);

人为的例子:

final CountDownLatch done = new CountDownLatch(1);

new Thread(new Runnable() {

    @Override
    public void run() {
        longProcessing();
        done.countDown();
    }
}).start();

//in your waiting thread:
boolean processingCompleteWithin1Second = done.await(1, TimeUnit.SECONDS);

注:CountDownLatches是线程安全的。



Answer 2:

你应该使用Condition

如果你想有,除了状态超时,看到await(long time, TimeUnit unit)



Answer 3:

Awaitility提供了一个简单而干净的解决方案:

等待()atMost(10,秒)。直到(() - >条件())。



Answer 4:

我一直在寻找像什么Awaitility提供了解决方案。 我想我在我的问题选择了一个不正确的示例。 我的意思是在你期待一个异步事件发生是由第三方服务创建和客户端无法修改提供通知服务的情况。 更为合理的例子是下面的一个。

class ThirdPartyService {

    ThirdPartyService() {
        new Thread() {

            public void run() {
                ServerSocket serverSocket = new ServerSocket(300);
                Socket socket = serverSocket.accept();
                // ... handle socket ...
            }
        }.start();
    }
}

class ThirdPartyTest {

    @Before
    public void startThirdPartyService() {
        new ThirdPartyService();
    }

    @Test
    public void assertThirdPartyServiceBecomesAvailableForService() {
        Client client = new Client();
        Awaitility.await().atMost(50, SECONDS).untilCall(to(client).canConnectTo(300), equalTo(true));
    }
}

class Client {

    public boolean canConnect(int port) {
        try {
            Socket socket = new Socket(port);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}


Answer 5:

你不应该睡觉,检查和睡眠和检查。 你要等待条件变量和具备的条件变化,醒来时它的时间做一些线程。



Answer 6:

好像你想要做的是检查车况,然后如果是假等到超时。 然后,在其他线程,notifyAll的一次操作完成。

服务员

synchronized(sharedObject){
  if(conditionIsFalse){
       sharedObject.wait(timeout);
       if(conditionIsFalse){ //check if this was woken up by a notify or something else
           //report some error
       }
       else{
           //do stuff when true
       }
  }
  else{
      //do stuff when true
  }
}

  synchronized(sharedObject){
   //do stuff to change the condition
   sharedObject.notifyAll();
 }

这应该为你做的伎俩。 你也可以做它用自旋锁,但你需要每次经过循环时间来检查超时。 该代码实际上可能是一个有点简单不过。



文章来源: Sleep and check until condition is true