我有以下代码调用两个Web服务。两个Web服务都返回非常大的响应,因此响应需要相当长的时间才能返回(一个Web服务请求为8秒,另一个为12秒)。请求以串行方式运行而不是并行时,总执行时间为20秒。
有什么方法可以修改我的代码来异步请求两个Web服务,并且能够在接近12秒的时间内处理响应,而不是当前需要的20秒?
String listOfCities;
String listOfCountries;
try {
listOfCities = service.getListOfCities(host+"service/cities");
listOfCountries = service.getListOfCountries(host+"service/countries");
} catch (Exception e) {
log.error("Failed to read service: " + e);
}
**感谢您的回复,我觉得这不是重复,因为我想停止执行我执行的两个线程,直到两者都收到了结果。以下解决方案显示了这一点**
答案 0 :(得分:4)
非常简单的实现,为了获得更多进展,您可能需要查看FutureTask
List<Thread> threadList = new ArrayList<>();
threadList.add(new Thread(new Runnable() {
@Override
public void run() {
try {
listOfCountries = service.getListOfCountries(host+"service/countries");
} catch (Exception e) {
log.error("Failed to read service: " + e);
}
}
}));
threadList.add(new Thread(new Runnable() {
@Override
public void run() {
try {
listOfCities = service.getListOfCities(host+"service/cities");
} catch (Exception e) {
log.error("Failed to read service: " + e);
}
}
}));
for (Thread t:threadList ){
t.start();
}
for (Thread t:threadList ){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//after both finish proceeds from here
注意字符串应该更全局地定义(类级别,而不是局部变量)
答案 1 :(得分:4)
我会尝试一些简单的事情,比如CompletableFuture:
import java.util.concurrent.CompletableFuture;
...
final CompletableFuture<String> listOfCities = CompletableFuture.supplyAsync(() -> service.getListOfCities(...));
final CompletableFuture<String> listOfCountries = CompletableFuture.supplyAsync(() -> service. getListOfCountries(...));
final CompletableFuture<Void> allCompleted = CompletableFuture.allOf(listOfCities, listOfCountries);
allCompleted.thenRun(() -> {
// whatever you want to do
});
请参阅这些examples以供参考。
答案 2 :(得分:2)
班级的全局变量。
String listOfCities;
String listOfCountries;
在函数中,这些方法将被调用,
try {//t is the object of the class like (Test t = new Test();)
new Thread(()-> t.listOfCities = service.getListOfCities(host+"service/cities");).start();
new Thread(()-> t.listOfCountries = service.getListOfCountries(host+"service/countries");).start();
} catch (Exception e) {
log.error("Failed to read service: " + e);
}
代码示例Demo here
通过@AniketSahrawat
答案 3 :(得分:0)
如果您希望执行时间按完成顺序排列,我建议您使用 guava 中的ListenableFuture
。 Futures.inCompletionOrder
将完成这项工作。
示例用法可能如下所示:
ExecutorService es;
Callable<String> task1;
Callable<String> task2;
//...
ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(es);
List<ListenableFuture<String>> yourTasks = new ArrayList<>();
yourTasks.add(listeningExecutorService.submit(task1));
yourTasks.add(listeningExecutorService.submit(task2));
for(Future f: Futures.inCompletionOrder(yourTasks)){
//process your task in completion order now
}