views:

187

answers:

2

Hi,

I'm using Glassfish 3 Web profile and can't get http workers to execute concurrently requests on a servlet.

This is how i observed the problem. I've made a very simple servlet, that writes the current thread name to the standard output and sleep for 10 seconds :

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println(Thread.currentThread().getName());
    try {
        Thread.sleep(10000); // 10 sec
    }
    catch (InterruptedException ex) {
    }
}

And when i'm running several simultaneous requests, I clearly see in the logs that the requests are sequentially executed (one trace every 10 seconds).

INFO: http-thread-pool-8080-(2)
(10 seconds later...)
INFO: http-thread-pool-8080-(1)
(10 seconds later...)
INFO: http-thread-pool-8080-(2)

etc.

All my GF settings are untouched - it's the out-of-the-box config (the default thread pool is 2 threads min, 5 max if I recall properly).

I really don't understand why the sleep() block all the others worker threads. Any insight would be greatly appreciated !

+1  A: 

Chris nailed it down in his comment. I copied your servlet, tested it as follows:

package com.stackoverflow.q2755338;

import java.io.IOException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test {

    public static void main(String... args) throws Exception {
        // Those are indeed called sequentially.
        System.out.println("Starting to fire 3 requests in current thread...");
        new TestURL().run();
        new TestURL().run();
        new TestURL().run();
        System.out.println("Finished firing 3 requests in current thread!");

        // But those are called three at once.
        System.out.println("Starting to fire 3 requests in each its own thread...");
        ExecutorService executor = Executors.newFixedThreadPool(3);
        executor.submit(new TestURL());
        executor.submit(new TestURL());
        executor.submit(new TestURL());
        System.out.println("Finished firing 3 requests in each its own thread!");
        executor.shutdown();
    }

}

class TestURL implements Runnable {

    @Override
    public void run() {
        try {
            System.out.println("Firing request...");
            new URL("http://localhost:8181/JavaEE6/test").openStream();
            System.out.println("Request finished!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

And the results on the server side were:

INFO: start: http-thread-pool-8181-(2)
(10 seconds)
INFO: end: http-thread-pool-8181-(2)
INFO: start: http-thread-pool-8181-(1)
(10 seconds)
INFO: end: http-thread-pool-8181-(1)
INFO: start: http-thread-pool-8181-(2)
(10 seconds)
INFO: end: http-thread-pool-8181-(2)

INFO: start: http-thread-pool-8181-(1)
INFO: start: http-thread-pool-8181-(2)
INFO: start: http-thread-pool-8181-(3)
(10 seconds)
INFO: end: http-thread-pool-8181-(1)
INFO: end: http-thread-pool-8181-(2)
INFO: end: http-thread-pool-8181-(3)
BalusC
I was manually sending requests using a browser (chrome)... Guess it doesn't actually send multiple requests if one of them is blocking ? In any case your client script works for me. Thanks.
difiouzz
You're welcome. Don't miss my JMeter suggestion in the other comment ;)
BalusC
Yup, I will definitely look into that. It's the beginning of my project, but hey, benchmark early, benchmark often :)
difiouzz
+1  A: 

Do you have the servlet running in single-thread mode ?
This would be in your web.xml

Romain Hippeau