import java.util.concurrent.TimeoutException;
import java.util.function.BooleanSupplier;
public interface WaitUntilUtils {
static void waitUntil(BooleanSupplier condition, long timeoutms) throws TimeoutException{
long start = System.currentTimeMillis();
while (!condition.getAsBoolean()){
if (System.currentTimeMillis() - start > timeoutms ){
throw new TimeoutException(String.format("Condition not met within %s ms",timeoutms));
}
}
}
}
7条答案
按热度按时间oknwwptz1#
假设你想要你所要求的,而不是重新设计你的代码的建议,你应该看看Awaitility。
例如,如果您要查看是否会在接下来的10秒内创建文件,请执行以下操作:
它主要用于测试,但也执行特定的请求技巧,即等待调用者指定的任意条件,而不需要显式同步或睡眠调用。如果您不想使用该库,只需阅读代码,了解它的工作方式。
在本例中,这归结为一个与问题类似的轮询循环,但将Java8lambda作为参数而不是内联条件传入。
4sup72z82#
您是否考虑过java.util.concurrent中的一些类-例如BlockingQueue?您可以用途:
然后在更改条件的代码中执行以下操作:
编辑:
另一个示例形式java.util.concurrent可以是CountDownLatch:
这样,您将等待10秒或直到锁存器达到零。要达到零,您需要做的是:
这样你就不需要使用锁了,而在@Adrian给出的Condition例子中是需要锁的。我认为这样更简单直接。
如果您不喜欢命名“Latch”或“Queue”,您可以将其 Package 到您自己的类中,即LimitedTimeCondition:
用法为:
vatpfxk53#
我没有在JDK中找到解决方案。我认为这个特性应该添加到JDK中。
下面是我用函数接口实现的内容:
6psbrbz94#
看一看Condition。
条件(也称为条件队列或条件变量)为一个线程提供了挂起执行的方法因为对该共享状态信息的访问发生在不同的线程中,所以它必须被保护,因此某种形式的锁与条件相关联,等待条件提供的关键属性是它原子地释放关联的锁并挂起当前线程,就像Object. wait一样。
Condition示例本身绑定到锁。若要获取特定Lock示例的Condition示例,请使用其newCondition()方法。
编辑:
mutmk8jj5#
您可能希望使用类似下面的代码(其中
secondsToWait
保存您希望等待以查看condition()
是否变为true的最大秒数。如果找到条件,变量isCondetionMet
将包含true,如果代码等待条件超时,则包含false。n8ghc7c16#
我采用了以下改编自原问题的解决方案:
在测试中使用时,它显示如下:
30byixjq7#
使用等待Awaritility: