1

Context:

I have done alot of reading, but only found this semi-relevant.

I have a servlet that calls a method from another Java class, while passing session-sensitive data. It is running on the Tomcat server.

It looks something like this:

@WebServlet(urlPatterns = {"/MyServlet", "/"})
public class MyServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException{ 
        HttpSession session = request.getSession(true); //Start a session
        String UserID = session.getId();                //Get a unique user ID
        MyClass cls = new MyClass();                    //Initialize my class
        String shortID = cls.newID(UserID);         //Call a method from class
        System.out.println("Your short ID is: " + shortID); //Print the result
    }
}

And say the class that I'm calling looks like this:

public class MyClass {

    public String newID(String UserID){
        String shortID;
            ... //Method for shortening the UserID
            return(shortID);
    }
}

The method of course requires much more processing than shown in this trivial example.

Question 1:

Now, my current understanding is that when n users call MyServlet simultaneously, Tomcat creates n threads in doGet method. So when method newID is called synchronously, Tomcat queues the threads and and allows them to execute one after another. Is this correct?

Question 2:

The problem arises when I have a large number of users, as the n th user will have to wait for newID method to be completed n-1 times, which might take a while. Therefore I will want to call the newID method asynchronously in order to run n threads in parallel, so to increase the throughput.

How can I achieve this?

Would you recommend using reflections, or wrapping the newID method inside a Runnable?

Does Tomcat take care of ExecutorService, or do I need to implement it too?

Any help will be much appreciated. Example code will be useful too!


Community
  • 1
  • 1
  • So your question is what is the maximum requests your tomcat handle at a given time and how to tweak that number? – rocketboy Aug 28 '13 at 13:50
  • @rocketboy It's more like "How to speed up the processing for a very large number of requests?" SotiriosDelimanolis, I changed it, thank you. – c.lindemann Aug 28 '13 at 13:58

1 Answers1

1

Question 1:

The Servlet Container keeps a pool of threads that it uses to handle requests. It also keeps a single instance of your servlet class. When a request comes in, it dispatches one of those threads which eventually hits the corresponding doXXX method. Threads aren't really queued. They work in parallel. So requests that come in at the same time are being handled parallelly (to a certain degree, read here.

Question 2:

Say you've configured your servlet container to have a pool of 10 threads to handle requests. But at some point you get 15 requests. Then yes, 5 requests will be queued awaiting an available thread. In that case, you can use Servlet 3.0 async support (read1, read2) to have the request handled in a separate thread (that the container also manages). When your processing is complete, a pool thread is re-dispatched to finish the request processing.

Read this for information about how to manage Threads.

Community
  • 1
  • 1
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • Thank you for your answer, it really taught me a lot! So what I understood is: 1) All concurrent threads will call the getID method simultaneously. 2) Any method inside MyClass is invoked asynchronously by default(?) 3) I will need to make my Servlet asynchronous in order to free up threads for extra request. Did I understand everything correctly? Does the Tomcat container provide the most efficient thread processing, or is there anything else I can do to improve the processing time for the nth user? – c.lindemann Aug 28 '13 at 15:05
  • 1) They're calling the same method but on different instances of the class, so unless they are blocked by something (synchronized at class level?), you don't have to worry. 2) Depends what you mean by asynchronous. Execution is synchronous in the context of the current thread. 3) Not necessarily. You can always increase the number of pool threads, depends on your needs. It seems to me like you're trying to do premature optimization. Don't. Write your code and test it. – Sotirios Delimanolis Aug 28 '13 at 15:09
  • In (2) I was worrying about thread interference, but it looks like you answered it in (1), thank you! I have already written all the code and now I am worrying about what will happen when tens of thousands of requests start coming in (and they will). My actual code is too long and specific to be used as an example for my question. I want this question to apply to those who will stumble upon it in the future. – c.lindemann Aug 28 '13 at 15:38
  • With a requirement like tens of thousands of concurrent requests (!!!), consider clustering. – Sotirios Delimanolis Aug 28 '13 at 15:41
  • Is there a chance you could link me to the source of your info, which says that "They're calling the same method but on different instances of the class"? I cannot find it anywhere, and want to lerarn more about it. – c.lindemann Aug 29 '13 at 14:07
  • @c.lindemann [This](http://tomcat.apache.org/tomcat-7.0-doc/architecture/requestProcess/requestProcess.pdf) is the official Tomcat request process sequence diagram. The fact is in your `doGet()` method, you create a new instance of `MyClass`. That instance is scoped to that method. No other outsider Thread has access to it. – Sotirios Delimanolis Aug 29 '13 at 14:10