3

Alright, I've already asked one question regarding this, but needed a bit more info. I'll try to be coherent with my question as much as I can. (Since I am not sure of the concepts).

Background

I have a java web project(dynamic). I am writing Restful webservices. Below is a snippet from my class

/services
class Services{
 static DataSource ds;
 static{
 ds = createNewDataSource;
 }

 /serviceFirst
 @Consumes(Something)
 @produces(Something)
 public List<Data> doFirst(){
  Connection con = ds.getConnection();
  ResultSet res = con.execute(preparedStatement);
  //iterate over res, and create list of Data.
  return list;
 }
}

This is a very basic functionality that I have stated here.

I've got tomcat server where I've deployed this. I've heard that Tomcat has a threadpool, of size 200 (by default). Now my question is that, how exactly does the threadpool work here.

Say I have two requests coming in at the same time. That means that 2 of the threads from the threadpool will get to work. Does this mean that both the threads will have an instance of my class Services? Because below is how I understand the threads and concurrency.

public class myThread extends Thread(){
    public void run(){
    //do whatever you wan to do here;
    }
}

In the above, when I call start on my Thread it will execute the code in run() method and all the objects that it creates in there, will belong to it.

now, coming back to the Tomcat, is there somewhere a run() method written that instantiates the Services class, and that is how the threadpool handles 200 concurrent requests. (Obviously, I understant they will require 200 cores for them to execute concurrently, so ignore that).

Because otherwise, if tomcat does not have 200 different threads having the same path of execution (i.e. my Services class), then how exactly will it handle the 200 concurrent requests.

Thanks

Kraken
  • 23,393
  • 37
  • 102
  • 162

1 Answers1

6

Tomcat's thread pool works, more or less, like what you would get from an ExecutorService (see Executors).

YMMV. Tomcat listens for requests. When it receives a request, it puts this request in a queue. In parallel, it maintains X threads which will continuously attempt to take from this queue. They will prepare the ServletRequest and ServletResponse objects, as well as the FilterChain and appropriate Servlet to invoke.

In pseudocode, this would look like

public void run() {
    while (true) {
        socket = queue.take();
        ServletRequest request = getRequest(socket.getInputStream());
        ServletResponse response = generateResponse(socket.getOutputStream());
        Servlet servletInstance = determineServletInstance(request);
        FilterChain chain = determineFilterChainWithServlet(request, servletInstance);
        chain.doFilter(request,response); // down the line invokes the servlet#service method
        // do some cleanup, close streams, etc.
    }
}

Determining the appropriate Servlet and Filter instances depends on the URL path in the request and the url-mappings you've configured. Tomcat (and every Servlet container) will only ever manage a single instance of a Servlet or Filter for each declared <servlet> or <filter> declaration in your deployment descriptor.

As such, every thread is potentially executing the service(..) method on the same Servlet instance.

That's what the Servlet Specification and the Servlet API, and therefore Tomcat, guarantee.


As for your Restful webservices, read this. It describes how a resource is typically an application scoped singleton, similar to the Servlet instance managed by a Servlet container. That is, every thread is using the same instance to handle requests.

Community
  • 1
  • 1
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • So, if I get it correctly. Each thread from the threadpool will (in practice) will hold the same instance of my Services class. So, I need not make the instance of my DataSource static, (no harm in making it static also, I guess), but even if I keep it non static, I can just instantiate it while declaring and use it afterwards. – Kraken Sep 23 '14 at 05:20
  • 1
    @Kraken That is correct, though I recommend using a proper inversion of control container to do the initialization and injection of the data source. – Sotirios Delimanolis Sep 23 '14 at 05:36