我编写了一个java程序,其中我应该知道两个嵌套的for循环是否可以在4秒内完成它们的执行。如果它们在4秒内完成它们的执行,那么程序应该继续,否则打破循环。我有三个列表 A 、B 和 C,我正在执行一些操作并将其添加到列表 B 中。即使对于列表 A 和 C 的小输入(如 3、6、8、4),我的程序也会抛出 run内存不足错误
我正在使用一个外部 for 循环来计算时间。如果两个 for 循环无法在 4 秒内完成执行,则应终止循环。我正在使用一个计数变量来跟踪 for 循环的执行,即使 for 循环在 4 秒之前完成执行,我也将终止外部 for 循环。
这是我的代码:
while(!(A.isEmpty())){
ArrayList<Long> B = new ArrayList<>();
for(long start = System.currentTimeMillis() ; start < System.currentTimeMillis() + 4 * 1000 ; ){
for(long i : A){
for(long j : C){
if(i!=j){
B.add(Math.abs(i-j));
}
}
count++;
if(count==A.size());
break;
}
}
}
这段代码有什么问题?我应该如何使其正确?
谢谢。
最佳答案
我认为这个设计并不是很稳健。我认为您可以考虑在这里使用两个线程,而不是在该循环中调用时间函数:
- 线程 A 启动线程 B,并等待 n 秒
- 线程 B 进行计算
- 当线程 A 唤醒时,它只是检查计算是否完成
或者,你的主线程启动 A 和 B; A 回来告诉你:现在该检查 B 的结果了。
对于你真正的问题;我猜这里有一个贡献者:
B.add(Math.abs(i-j));
你看到 B(顺便说一句,对于数字列表来说,这个名字真的很糟糕!)需要 Long 对象。因此,这个小调用每次迭代至少创建一个 Long 对象。然后你迭代 A 和 C。那里没有任何 sleep 或延迟。这意味着您的代码除了迭代循环和创建新对象来填充 B 列表之外,什么都不做。
现在:您认为 4 秒内会看到多少次循环迭代?足以创建数以百万计的对象?!然后:动态增长的列表很好,但是当 ArrayList 不断超出其容量并需要增长时,您明白这意味着吗?!您知道这意味着创建新数组并复制所有值吗?!
我想说的是:仔细看看那里到底做了多少工作;以及您的代码中对原始/引用长/长的装箱量(取消)装箱量。
测试这些想法的一个(也许是简单的方法):将代码从使用长整型列表更改为使用具有长整型值的固定数组。这将产生一个很好的副作用 - 它将迫使您预先考虑您实际想要创建多少个数组槽。在您的解决方案中,您只需不断循环并添加新对象(如上所述;导致 B 列表不断重新容量增加操作)。
关于java 中的 java.lang.OutOfMemoryError 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40074477/