@Async prevent a thread to continue until other thread have finished(@Async 阻止线程继续,直到其他线程完成)
问题描述
我有一个应用程序需要计算一定次数的东西.此计算函数具有注释 @Async(来自 Spring 框架),这使得可以在 4 个线程上运行这些计算.问题是我需要大约 40000 次这样的计算,我想知道所有计算的开始和结束之间的时间,所以我看到调用计算函数的 for 循环之前和之后的时间.但是现在所有的计算都放在一个队列中,所以 for 循环立即结束,时间大约是 1 秒,而计算需要几个小时才能完成.我尝试将最大队列大小设置为大约 100(也有助于减少内存使用),但这也不是解决方案,因为我会错过总时间的最后 100 次计算.有没有办法在 for 循环之后暂停执行代码,直到所有线程完成工作,但仍然能够使用 @Async 注释?
这是一些说明相同问题的代码:
执行类:
公共类 Foo {公共无效执行BlaALotOfTimes(){很久以前 = System.currentTimeMillis();for (int i = 0; i<40000; i++) {执行布拉();}很久之后 = System.currentTimeMillis();System.out.println("大量bla执行的时间:" + (after - before)/1000.0 + " seconds.");}}
以及执行计算的类:
@Service公共类酒吧{@异步公共无效执行Bla(){System.out.println("Bla!");}}
这将导致以下输出(假设 Foo 中的代码执行得无限快):
<上一页>执行大量 bla 所花费的时间:0.0 秒.布拉!布拉!布拉!布拉!...等等
如果你需要等待执行完成,那么你可以返回一个 Future
作为返回值,例如
@Async公共未来<无效>执行布拉(){System.out.println("Bla!");return new AsyncResult<Void>(null);}
这有点人为,因为没有返回实际值,但它仍然允许调用代码等待所有执行完成:
public void executeBlaALotOfTimes() {很久以前 = System.currentTimeMillis();收藏<未来<虚空>>futures = new ArrayList>();for (int i = 0; i<40000; i++) {期货.add(executeBla());}for (Future<Void> 未来:期货) {未来.get();}很久之后 = System.currentTimeMillis();System.out.println("大量bla执行的时间:" + (after - before)/1000.0 + " seconds.");}
在这里,第一个循环触发异步任务并将未来存储在列表中.秒循环然后迭代未来,等待每个完成.
I have an application where for a certain number of times something needs to be calculated. This calculation function has the annotation @Async (from the Spring Framework), that makes it possible to run these calculations on 4 threads. The problem is that I need about 40000 of these calculations and I want to know the time between the start and end of all the calculations, so I see what time it is before and after the for-loop that calls the calculation functions. But now all the calculations are put in a queue, so the for loop finishes immediately and the time is something like 1 second, while it takes a couple of hours for the calculations to complete. I've tried setting a max queue size to about 100 (also good to reduce memory usage) but this is also no solution since I'll miss the last 100 calculations in the total time it takes. Is there a way to pause the executing code just after the for loop until all threads have finished doing their work, but still being able to use the @Async annotation?
This is some code that illustrates the same problem:
Executing class:
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.");
}
}
And the class that performs the calculations:
@Service
public class Bar {
@Async
public void executeBla() {
System.out.println("Bla!");
}
}
This would result in the following output (assuming the code in Foo executes infinitely fast):
Time it took for a lot of bla to execute: 0.0 seconds. Bla! Bla! Bla! Bla! . . . etc
If you need to wait for the executions to finish, then you can return a Future
as a return value, e.g.
@Async
public Future<Void> executeBla() {
System.out.println("Bla!");
return new AsyncResult<Void>(null);
}
This is slightly artificial, since there's no actual value being returned, but it will still allow the calling code to wait for all executions to finish:
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.");
}
Here, the first loop fires off the async tasks and stores the futures in a list. The seconds loop then iterates over the futures, waiting for each one to finish.
这篇关于@Async 阻止线程继续,直到其他线程完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:@Async 阻止线程继续,直到其他线程完成


- 从 finally 块返回时 Java 的奇怪行为 2022-01-01
- Java包名称中单词分隔符的约定是什么? 2022-01-01
- Safepoint+stats 日志,输出 JDK12 中没有 vmop 操作 2022-01-01
- Jersey REST 客户端:发布多部分数据 2022-01-01
- Spring Boot连接到使用仲裁器运行的MongoDB副本集 2022-01-01
- C++ 和 Java 进程之间的共享内存 2022-01-01
- Eclipse 插件更新错误日志在哪里? 2022-01-01
- value & 是什么意思?0xff 在 Java 中做什么? 2022-01-01
- 如何使用WebFilter实现授权头检查 2022-01-01
- 将log4j 1.2配置转换为log4j 2配置 2022-01-01