我有一个应用程序,在某些情况下需要计算某些次数。此计算功能具有@Async注释(来自Spring Framework),可以在4个线程上运行这些计算。问题是我需要大约40000个这些计算,并且我想知道所有计算的开始和结束之间的时间,因此我看到在调用计算函数的for循环之前和之后的时间是什么。但是现在所有计算都放入队列中,因此for循环立即完成,时间大约为1秒,而计算要花几个小时才能完成。我尝试将最大队列大小设置为大约100(这也有助于减少内存使用),但这也不是解决方案,因为我将错过总花费的最后100次计算。
这是一些代码,它说明了相同的问题:
执行类:
public class Foo { public void executeBlaALotOfTimes() { long before = System.currentTimeMillis(); for (int i = 0; i<40000; i++) { executeBla(); } long after = System.currentTimeMillis(); System.out.println("Time it took for a lot of bla to execute: " + (after - before) / 1000.0 + " seconds."); } }
以及执行计算的类:
@Service public class Bar { @Async public void executeBla() { System.out.println("Bla!"); } }
这将导致以下输出(假设Foo中的代码无限快速地执行):
bla执行大量时间:0.0秒。 布拉! 布拉! 布拉! 布拉! 。 。 。 等等
如果您需要等待执行完成,则可以返回a Future作为返回值,例如
Future
@Async public Future<Void> executeBla() { System.out.println("Bla!"); return new AsyncResult<Void>(null); }
这是人为的,因为没有返回实际值,但是它仍然允许调用代码等待所有执行完成:
public void executeBlaALotOfTimes() { long before = System.currentTimeMillis(); Collection<Future<Void>> futures = new ArrayList<Future<Void>>(); for (int i = 0; i<40000; i++) { futures.add(executeBla()); } for (Future<Void> future : futures) { future.get(); } long after = System.currentTimeMillis(); System.out.println("Time it took for a lot of bla to execute: " + (after - before) / 1000.0 + " seconds."); }
在这里,第一个循环触发异步任务并将期货存储在列表中。然后秒循环遍历期货,等待每一个期货结束。