java - 主线程不等待 CompletableFuture.runAsync() 并返回响应
问题描述
我有一个函数,它有一个调用方法,它在内部调用一个soap API,执行大约需要22秒,代码中也很少有其他方法,所以完全deleteSoemthing()(下面的代码)方法需要24秒,
现在,我尝试在单独的线程中运行耗时方法,所以我的假设是即使它是单独的线程,它也只会优化到 2 秒,因为它从总共 24 秒中花费了 22 秒。
所以它可能需要 22 秒而不是 24 秒,因为它是并行运行的。
但是当我通过邮递员运行它时,它只需要 2 秒即可执行,我的意思是响应会在 2 秒内返回。并且单独的线程继续运行(当我通过调试检查时)。
所以,我的疑问是,主线程是否不等待此任务完成并发送回响应。或者它只是发送响应并继续在后台运行异步任务
void deleteSomething(){
CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
try {
invoke("invoking a soap API"));
} catch (Exception e) {
e.printStackTrace();
}
});
//some other code
}
解决方案
如果您希望主线程(请求)并行处理“一些其他代码”和“调用 SOAP API”,然后组合并将响应返回给最终用户,那么这将不起作用。
当我们创建一个 CompletableFuture 实例时,它会在另一个线程中分离计算并立即返回 Future。如果你需要阻塞结果,那么你需要调用它的get方法。然而,这个过程仍然需要 22+2 = 24 秒才能返回响应。
要并行运行这两个任务,您应该创建两个Callable (s) 并将它们提交给ExecutorService
例如。
public void deleteSomething(){
ExecutorService executorService = Executors.newFixedThreadPool(2);
Collection<Callable<Void>> callables = new ArrayList<>();
callables.add(() -> doSomeOtherTask());
callables.add(() -> invokeSoapApi());
try {
List<Future<Void>> taskFutureList = executorService.invokeAll(callables);
taskFutureList.get(0).get();
taskFutureList.get(1).get();
} catch (InterruptedException | ExecutionException e) {
//error
}
}
public Void doSomeOtherTask() {
//some other code
return null;
}
public Void invokeSoapApi() {
//soap api call
return null;
}
请注意,线程池应在应用程序启动时创建。因此,如果您真的希望使用它,那么您应该将“executorService”定义为实例变量。例如。
@Service
public class MyService {
...
...
private ExecutorService executorService = Executors.newFixedThreadPool(2);
...
...
//your methods
}
推荐阅读
- c++11 - 可变参数模板继承中的运算符重载
- python - 在 for 循环之后停止对 gzip 压缩的文本文件的迭代
- python - 如何使用 MATLAB 内核运行 Python 代码以加速计算?
- javascript - 在 codeigniter 和 JavaScript 中自动增加序列号
- swift - 将图像添加到 swift Playground [iPad]
- java - 使用 xml 中的字段类型将 XML 解析为 java 对象
- scala - 将s3“目录”复制到本地目录
- php - 我无法使用 Laravel 和 Dropzone.js 上传文件
- java - 为什么使用 2 的幂来实现 HashMap?
- excel - 使用类对象将数据文件汇总到字典中