I need to send multiple requests to many different web services and receive the results. The problem is that, if I send the requests one by one it takes so long as I need to sen
That is a simple fork-join approach, but for clarity, you can start any number of threads and retrieve the results later as they are available, such as this approach.
ExecutorService pool = Executors.newFixedThreadPool(10);
List> tasks = new ArrayList<>();
tasks.add(new Callable() {
public String call() throws Exception {
Thread.sleep((new Random().nextInt(5000)) + 500);
return "Hello world";
}
});
List> results = pool.invokeAll(tasks);
for (Future future : results) {
System.out.println(future.get());
}
pool.shutdown();
UPDATE, COMPLETE:
Here's a verbose, but workable solution. I wrote it ad hoc, and have not compiled it. Given the three lists have diffent types, and the WS methods are individual, it is not really modular, but try to use your best programming skills and see if you can modularize it a bit better.
ExecutorService pool = Executors.newFixedThreadPool(10);
List>> stasks = new ArrayList<>();
List>> dtasks = new ArrayList<>();
List>> ptasks = new ArrayList<>();
stasks.add(new Callable>() {
public List call() throws Exception {
return retrieveStdWS1();
}
});
stasks.add(new Callable>() {
public List call() throws Exception {
return retrieveStdWS2();
}
});
stasks.add(new Callable>() {
public List call() throws Exception {
return retrieveStdWS3();
}
});
dtasks.add(new Callable>() {
public List call() throws Exception {
return retrieveDocWS4();
}
});
dtasks.add(new Callable>() {
public List call() throws Exception {
return retrieveDocWS5();
}
});
dtasks.add(new Callable>() {
public List call() throws Exception {
return retrieveDocWS6();
}
});
ptasks.add(new Callable>() {
public List call() throws Exception {
return retrievePtWS7();
}
});
ptasks.add(new Callable>() {
public List call() throws Exception {
return retrievePtWS8();
}
});
ptasks.add(new Callable>() {
public List call() throws Exception {
return retrievePtWS9();
}
});
List>> sresults = pool.invokeAll(stasks);
List>> dresults = pool.invokeAll(dtasks);
List>> presults = pool.invokeAll(ptasks);
for (Future> future : sresults) {
this.studentsResults.addAll(future.get());
}
for (Future> future : dresults) {
this.doctorsResults.addAll(future.get());
}
for (Future> future : presults) {
this.patientsResults.addAll(future.get());
}
pool.shutdown();
Each Callable
returns a list of results, and is called in its own separate thread.
When you invoke the Future.get()
method you get the result back onto the main thread.
The result is NOT available until the Callable
have finished, hence there is no concurrency issues.