2

I've a web application which needs to be extremely fast. But for processing it requires access for multiple data sources. Therefore I decided that it might be useful to make a parallel calls for optimization.

Basically I want to make many different db calls in parallel. Could you please recommend me simple and reliable way and technologies for achieving my goal, it would be useful if you could provide few frameworks and design patterns.

Right now I am using Spring.

3
  • 1
    ExecutorService, Spring Scheduling, akka and probably some other options out there. Commented Apr 1, 2015 at 15:34
  • If you are running in a servlet container, e.g. tomcat or jetty, then each incoming request is already handled in its own thread and will access you db in parallel. Commented Apr 1, 2015 at 16:16
  • First (DB) a solid DB scheme: writable user data in a separate table from the mostly read-only user data. Then (traffic) prevent bloated queries, restrict the columns. Last comes the asynchrone architecture you asked for. This can be any wild thing like a Spaces for messages with results. That has to be tried with a built test scenario. Commented Jun 10, 2015 at 11:32

1 Answer 1

2

You can use the new Java 8 CompletableFuture. It allows to use asynchronously existing synchronous method.

Say you have a list of requests in the form List<DBRequest> listRequest that you want to run in parallel. You can make a stream and launching all requests asynchronously in the following way.

List<CompletableFuture<DBResult>> listFutureResult =
                     listRequest.stream()
                                .map(req -> CompletableFuture.supplyAsync(
                                              () -> dbLaunchRequest(req), executor))
                                .collect(Collectors.toList());    
List<DBResult> listResult = 
                     listFutureResult.stream()
                                     .map(CompletableFuture::join)
                                     .collect(Collectors.toList());

To be effective you have to write your own custom Executor

private final Executor executor = 
    Executors.newFixedThreadPool(Math.min(listRequest.size(), 100),
                                 new ThreadFactory(){
               public Thread newThread(Runnable r){
                    Thread t = new Thread(r);
                    t.setDaemon(true);
                    return t;
               }
});

Like this you can have enough threads but not too much. Marking threads to deamons allows you to finish the program even if one thread is blocked.

You can find clear explanations about these techniques in the chapter 11 of the book Java 8 in action

== UPDATE for Java 7 ==

If you are stick with Java 7, you can use the following solution:

class DBResult{}
class DBRequest implements Callable<DBResult>{
    @Override
    public DBResult call(){return new DBResult();}
}
class AsyncTest{
   public void test(){
     try {
         for(Future<DBResult> futureResult : ((ExecutorService)executor).invokeAll(listRequest)){
             futureResult.get();
         }
     } catch (InterruptedException | ExecutionException ex) {
         Logger.getLogger(SoTest.class.getName()).log(Level.SEVERE, null, ex);
     }
   }
}

All requests are run asynchronously and you then wait for their completion, in the order of the list.

Finally, to answer the subsidiary question in the comment, you don't have to create a thread pool for each request.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks for your answer. Does that mean, I should not create a thread pool every time I do a new request and just reuse the old one? How expensive is that create a new thread pool every single request? I've many small request where I need access multiple data sources, so probably best way is to create a one single thread pool and reuse it? Could you please provide similar example for JAVA7?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.