我正在编写一些代码,并想知道它是不是通过在每次迭代开始时调用Thread.sleep(10)
来限制循环。我的另一个选择是在较长的时间间隔内调用Thread.sleep
次,但这对我编码的内容来说并不是最佳选择。有没有人知道我是否应该关注在使用Thread.sleep()
时以非常快的速度恢复/暂停Java线程的开销,是否还有另一种我应该关注的选择? - 邓肯克雷布斯
这是我的用例更详细:
我有一个回溯测试数据源,它遍历一个大的Quote对象列表,我想限制报价消耗的速度,这样我可以加快或减慢我的后退测试时间。对于初学者,我没有看到除Thread.sleep()之外的其他选项,如果是这种情况,那么我可以在每个Quote消耗很短的时间之后睡眠或者批量消耗集合然后在消费之前睡觉下一批。如果我可以一次限制这个消费线程1的引用,那么我用来理解tick数据的其余框架运行得最好,希望这是有道理的!
答案 0 :(得分:3)
您不应该加速或减慢循环以进行测试 - 而是将循环设计为与测试代码显式同步(例如通过CountDownLatch或Condition)。依赖于被测代码执行速度的测试代码本质上是不稳定的,您将看到问题。
答案 1 :(得分:1)
有没有人知道我是否应该关注使用Thread.sleep()时以非常快的速度恢复/暂停Java线程的开销,
可能。睡觉放弃CPU,没有保证它会立即醒来。在极少数情况下可能需要11或15毫秒。唤醒后,CPU将缓慢运行约200微秒,同时CPU缓存再次升温。
还有另一种我应该关注的选择吗?
永远不要睡觉。它的成本更高,但您的代码不会变慢。
对于初学者,我没有看到Thread.sleep(),
以外的其他选项
LockSUpport.park(nanos)具有更高的精度。
希望这是有道理的!
我会在最初发生的报价更新之间按照时间长度睡觉。根据您的使用情况,我会在10到100毫秒之间设置一个上限。如果你想要精确,你可以忙着等待你需要的延迟。
答案 2 :(得分:0)
听起来你可能有多个生产者和多个消费者,每个消费者都有自己的线程。如果是这样,你可以通过配置注入减少它们的数量。这样你就可以拥有1个生产者,1个消费者。如果你的生产者是在测试代码中创建的,那么你应该没有问题限制它,这样你就可以限制整个系统。您可以使用Thread.sleep
或同步原语。
但是,如果您的测试目标实际上是弄清楚消费者对数据做了什么,那么我所做的实际上是公开可行的方法,以便我可以直接调用它,只使用预定义数据调用一次。如果这种方法处于某种无限循环中,那么在正常情况下,它可能会等待数据在处理之后完成。但在测试模式下,只会运行有用的部分循环。最大的缺点是暴露出一种你可能不想暴露的方法。
// Method used by Thread class.
private void foo() {
while(true) {
// Blocking wait for data.
data = getData();
// Processing
doStuff(data);
}
}
public void doStuff(Data data) {
// do useful thing here.
}