2

I have a Servlet which recieves a request, has to process 5 tasks (Grab data Form external Servers) and send all the data back to the client ordered.

How to process the 5 Task simultaneously and continue with the servlet code after all 5 tasks are completed?

user3876178
  • 241
  • 1
  • 4
  • 11

3 Answers3

1

You can use CoundDownLatch

A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

sample code:

    CountDownLatch startSignal = new CountDownLatch(1);
    CountDownLatch doneSignal = new CountDownLatch(5); // 5 tasks

    class Worker implements Runnable {
        private final CountDownLatch startSignal;
        private final CountDownLatch doneSignal;
        private final int threadNumber;

        // you can pass additional arguments as well
        Worker(CountDownLatch startSignal, CountDownLatch doneSignal,
                                                   int threadNumber) {
            this.startSignal = startSignal;
            this.doneSignal = doneSignal;
            this.threadNumber = threadNumber;
        }

        public void run() {
            try {
                startSignal.await();
                doWork(); // actual work to be performed here    
                doneSignal.countDown();
            } catch (InterruptedException ex) {
                LOGGER.error(ex);
            }
        }
    }

    // 5 new threads are started
    for(int i=1;i<=5;i++){
        new Thread(new Worker(startSignal, doneSignal, i)).start();
    }

    startSignal.countDown(); // let all threads proceed
    try {
        doneSignal.await(); // wait for all to finish
        // all 5 tasks are finished and do whatever you want to do next
    } catch (InterruptedException interruptedException) {
        LOGGER.error(interruptedException);
    }

Read more... and Find more examples...

Community
  • 1
  • 1
Braj
  • 46,415
  • 5
  • 60
  • 76
  • Thx, thats a good solution. But in your Example I just start the same task (here: doWork()) 5 times in 5 threads. How to start 5 different tasks? – user3876178 Jul 27 '14 at 16:03
  • As in the code I have started 5 threads. just check the threadNumber in the worker class and do based on that number. – Braj Jul 27 '14 at 16:06
1

Another option is the ExecutorService. There are a variety of examples available including the following:

Here is some example code taken from the first link found above:

ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
while(...) {
  taskExecutor.execute(new MyTask());
}
taskExecutor.shutdown();
try {
  taskExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
  ...
}
Community
  • 1
  • 1
Sid
  • 1,144
  • 10
  • 21
  • have you tested it for Servlet in clustered environment? – Braj Jul 27 '14 at 16:23
  • @user3218114 Your original question doesn't mention anything about a clustered environment. This is just some sample code and references to get you started. You'll have to try it out and see if this fits your requirements. – Sid Jul 27 '14 at 16:26
  • I am not OP. I used CountDownLatch in a live application and after that I have shared it as an answer. I am just asking. No worries. – Braj Jul 27 '14 at 16:28
  • @user3218114 Right, sorry. Your username confused me. It's very similar to OP. You need a unique one lol! I've used the `ExecutorService` in a live application but it wasn't in a clustered environment. But I believe that it is widely used in Java. – Sid Jul 27 '14 at 16:31
  • yes Sid If you look at my previous edit then I suggested to use ExecutorService then I haven't tested it hence I have edited my post again. – Braj Jul 27 '14 at 16:32
0

5 seconds is too long, it might take up the web server resource, you can let the client to send a request A, which trigger your 5 seconds task, but it don't wait, return immediately.Since you know it will take 5 seconds, you can send another request B, 5 seconds later, to get the data. If data not ready yet, you can request after another 5 seconds, until MAX_RETRY_COUNT (defined by yourself) reached.

Eric
  • 22,183
  • 20
  • 145
  • 196