The usual pattern of doing this is -
- Create an interface that is implemented by classes which contain the logic to understand the API of different services like Twitter, Facebook etc. (say ISocialServiceAPI)
- Create a class that implements Callable (say HttpTask) and pass in an object which implements ISocialServiceAPI
- Create an ExecutorService to which you will submit tasks
- Create a Collection of callables that you want to execute
- Use the invokeAll method provided by the ExecutorService along with the time out you need. It returns a List of futures
- Timed out tasks are cancelled by the ExecutorService. Catch the CancellationException and handle it
//Generate a list callables
List<HttpTask> httpTaskList= new ArrayList<HttpTask>();
httpTaskList.add(new TwitterAPIRequest());
httpTaskList.add(new FacebookAPIRequest());
List<Future<ApiResponse>> futures = null;
try {
//Submit the list of callable objects
futures = exec.invokeAll(httpTaskList,
timeout, TimeUnit.SECONDS);
} catch (InterruptedException iex) {
//Handle
}
if(null != futures) {
finalResponse = new ArrayList<ApiResponse>( httpTaskList.size() );
Iterator<HttpTask> httpTaskIter = httpTaskList.iterator();
for (Future<ApiResponse> f : futures) {
HttpTask httpTask = httpTaskIter.next();
try {
finalResponse.add( f.get() );
} catch(InterruptedException iex) {
//Handle
} catch (ExecutionException eex) {
finalResponse.add( httpTask.getFailureResponse() );
} catch (CancellationException cex) {
finalResponse.add( httpTask.getTimeoutResponse() );
}
}
} else {
//Handle
}
If you have access to it, refer to Chapter 6 of Java Concurrency in Practice.