returns以后如何并行调用一个方法呢?
How to call a method in parallel which returns the future?
我有一个异步方法,如下所示,它调用我的任务 class,我的任务 class 完成所有工作。
@Override
public Future<DataResponse> executeAsync(DataKey key) {
Future<DataResponse> future = null;
try {
Task task = new Task(key, restTemplate);
future = executor.submit(task);
} catch (Exception ex) {
// logging exception here
}
return future;
}
下面是我的 Task
class,它完成了所有工作:
public class Task implements Callable<DataResponse> {
private DataKey key;
private RestTemplate restTemplate;
public Task(DataKey key, RestTemplate restTemplate) {
this.key = key;
this.restTemplate = restTemplate;
}
@Override
public DataResponse call() throws Exception {
// some code here
}
}
现在我需要并行调用 executeAsync
方法,然后创建一个 List<DataResponse>
对象并 return 它。
@Override
public List<DataResponse> executeSync(DataKey key) {
List<DataResponse> responseList = new ArrayList<DataResponse>();
// make a List of DataKey using single key passed to this method.
List<DataKey> keys = new ArrayList<DataKey>();
for(DataKey key : keys) {
}
}
如何并行调用 executeAsync
方法并 return 返回 responseList
?在我的 keys
列表中,我将有六个 DataKey
对象。
如果您希望 return 一个 List<DataResponse>
包含由 Task#call
编辑的 DataResponse
个对象 return,您不能异步执行此操作.您需要在 executeSync
内阻塞以等待所有期货的结果。
List<Future> futures = new ArrayList<>(keys.size());
for(DataKey key : keys) {
Future<DataResponse> future = executeAsync(key);
futures.add(future);
}
for (Future<DataResponse> future : futures) {
try {
responseList.add(future.get());
} catch (Exception e) {
// do something else.
}
return responseList
}
使用 Future
更合适的解决方案是使用 CompletionService
,详见 here。
在 Java 8 中,您应该使用 CompletableFuture
(或 Guava 的 ListenableFuture
)来执行异步任务。您仍然可以执行我上面所做的,或者您可以更改代码以充分利用延续任务。
您可以调用Executor服务的invokeAll方法,将任务列表提交给它。 Executor Service 将并行执行任务。
这与:
1. 从 executeSync 方法中的 for 循环并行调用 executeAsync。
2. 从executeSync 方法中的for 循环依次调用executeAsync 方法。
没有理由并行执行它,因为它在内部已经并行运行。您唯一需要做的就是为每个项目调用异步方法并将结果 Future
存储在列表中。此循环结束后,您需要遍历那些 Future
的列表,并对它们中的每一个调用 get()
给出结果。这些结果列表您将 return 作为 return 值。
我有一个异步方法,如下所示,它调用我的任务 class,我的任务 class 完成所有工作。
@Override
public Future<DataResponse> executeAsync(DataKey key) {
Future<DataResponse> future = null;
try {
Task task = new Task(key, restTemplate);
future = executor.submit(task);
} catch (Exception ex) {
// logging exception here
}
return future;
}
下面是我的 Task
class,它完成了所有工作:
public class Task implements Callable<DataResponse> {
private DataKey key;
private RestTemplate restTemplate;
public Task(DataKey key, RestTemplate restTemplate) {
this.key = key;
this.restTemplate = restTemplate;
}
@Override
public DataResponse call() throws Exception {
// some code here
}
}
现在我需要并行调用 executeAsync
方法,然后创建一个 List<DataResponse>
对象并 return 它。
@Override
public List<DataResponse> executeSync(DataKey key) {
List<DataResponse> responseList = new ArrayList<DataResponse>();
// make a List of DataKey using single key passed to this method.
List<DataKey> keys = new ArrayList<DataKey>();
for(DataKey key : keys) {
}
}
如何并行调用 executeAsync
方法并 return 返回 responseList
?在我的 keys
列表中,我将有六个 DataKey
对象。
如果您希望 return 一个 List<DataResponse>
包含由 Task#call
编辑的 DataResponse
个对象 return,您不能异步执行此操作.您需要在 executeSync
内阻塞以等待所有期货的结果。
List<Future> futures = new ArrayList<>(keys.size());
for(DataKey key : keys) {
Future<DataResponse> future = executeAsync(key);
futures.add(future);
}
for (Future<DataResponse> future : futures) {
try {
responseList.add(future.get());
} catch (Exception e) {
// do something else.
}
return responseList
}
使用 Future
更合适的解决方案是使用 CompletionService
,详见 here。
在 Java 8 中,您应该使用 CompletableFuture
(或 Guava 的 ListenableFuture
)来执行异步任务。您仍然可以执行我上面所做的,或者您可以更改代码以充分利用延续任务。
您可以调用Executor服务的invokeAll方法,将任务列表提交给它。 Executor Service 将并行执行任务。
这与: 1. 从 executeSync 方法中的 for 循环并行调用 executeAsync。 2. 从executeSync 方法中的for 循环依次调用executeAsync 方法。
没有理由并行执行它,因为它在内部已经并行运行。您唯一需要做的就是为每个项目调用异步方法并将结果 Future
存储在列表中。此循环结束后,您需要遍历那些 Future
的列表,并对它们中的每一个调用 get()
给出结果。这些结果列表您将 return 作为 return 值。