@Async阻止线程继续执行,直到其他线程完成
我有一个应用程序,在某些情况下需要计算某些次数。此计算功能具有@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.");
}
}
以及执行计算的类:
@Servicepublic class Bar {
@Async
public void executeBla() {
System.out.println("Bla!");
}
}
这将导致以下输出(假设Foo中的代码无限快速地执行):
bla执行大量时间:0.0秒。布拉!
布拉!
布拉!
布拉!
。
。
。
等等
回答:
如果您需要等待执行完成,则可以返回a Future
作为返回值,例如
@Asyncpublic 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.");
}
在这里,第一个循环触发异步任务并将期货存储在列表中。然后秒循环遍历期货,等待每一个期货结束。
以上是 @Async阻止线程继续执行,直到其他线程完成 的全部内容, 来源链接: utcz.com/qa/414677.html