等待 x 秒或直到条件变为真
2022-09-01 16:30:08
如何等待 x 秒或直到条件变为真?在等待时应定期测试该病症。目前我正在使用这个代码,但应该有一个简短的函数。
for (int i = 10; i > 0 && !condition(); i--) {
Thread.sleep(1000);
}
如何等待 x 秒或直到条件变为真?在等待时应定期测试该病症。目前我正在使用这个代码,但应该有一个简短的函数。
for (int i = 10; i > 0 && !condition(); i--) {
Thread.sleep(1000);
}
假设你想要你所要求的,而不是重新设计代码的建议,你应该看看Waitility。
例如,如果要查看是否将在接下来的 10 秒内创建文件,请执行如下操作:
await().atMost(10, SECONDS).until(() -> myFile.exists());
它主要针对测试,但执行特定的请求技巧,即等待调用方指定的任意条件,而无需显式同步或休眠调用。如果您不想使用该库,只需阅读代码即可了解其执行操作的方式。
在这种情况下,这可以归结为与问题类似的轮询循环,但是使用Java 8 lambda作为参数而不是内联条件传入。
你有没有想过java.util.concurrent中的一些类 - 例如BlocklingQueue?您可以使用:
BlockingQueue<Boolean> conditionMet = new BlockingQueue<Boolean>;
conditionMet.poll(10,TimeUnit.SECONDS);
然后在更改条件的代码中执行以下操作:
conditionMet.put(true);
编辑:
另一个示例形式java.util.concurrent可能是CountDownLatch:
CountDownLatch siteWasRenderedLatch = new CountDownLatch(1);
boolean siteWasRendered = siteWasRenderedLatch.await(10,TimeUnit.SECONDS);
这样,您将等待 10 秒钟或直到闩锁达到零。要达到零,您所要做的就是:
siteWasRenderedLatch.countDown();
这样,您就不需要使用@Adrian提供的条件示例中需要的锁。我认为它只是更简单,更直接。
如果你不喜欢命名“Latch”或“Queue”,你可以随时将其包装到你自己的类中,即LimitedTimeCondition:
public class LimitedTimeCondition
{
private CountDownLatch conditionMetLatch;
private Integer unitsCount;
private TimeUnit unit;
public LimitedTimeCondition(final Integer unitsCount, final TimeUnit unit)
{
conditionMetLatch = new CountDownLatch(1);
this.unitsCount = unitsCount;
this.unit = unit;
}
public boolean waitForConditionToBeMet()
{
try
{
return conditionMetLatch.await(unitsCount, unit);
}
catch (final InterruptedException e)
{
System.out.println("Someone has disturbed the condition awaiter.");
return false;
}
}
public void conditionWasMet()
{
conditionMetLatch.countDown();
}
}
用法是:
LimitedTimeCondition siteRenderedCondition = new LimitedTimeCondition(10, TimeUnit.SECONDS);
//
...
//
if (siteRenderedCondition.waitForConditionToBeMet())
{
doStuff();
}
else
{
System.out.println("Site was not rendered properly");
}
//
...
// in condition checker/achiever:
if (siteWasRendered)
{
condition.conditionWasMet();
}