知识库 --allocate the servlet(54)

来源:互联网 发布:淘宝怎么给客服发图片 编辑:程序博客网 时间:2024/06/03 00:37

Allocating the Servlet

The StandardWrapperValve’s invoke method calls the wrapper’s allocate method to obtain an instance of the requested servlet. The StandardWrapper class therefore must have the implementation of this method.

The signature of the allocate method is as follows:

    public javax.servlet.Servlet allocate() throws ServletException;

Notice that the allocate method returns an instance of the requested servlet.

The necessity for supporting STM servlets makes the allocate method a bit more complex. In fact, there are two parts in the allocate method, one to cater for non-STM servlets and the other for STM servlets. The first part has the following skeleton.

    if(!singleThreadModel){        //returns a non-STM servlets instance    }

The singleThreadModel is a boolean that indicates whether the servlet represented by this StandardWrapper is an STM servlet. The initial value for singleThreadModel if false, but the loadServlet method tests the servlet it is loading and set this boolean if the servlet is a STM servlet.

The second part of the allocate method is executed if singleThreadModel is true. The skeleton of the second part is as follows:

    synchronized(instancepool){        //returns an instance of the servlet from the pool    }

For non-STM servlets, the StandardWrapper defines a variable named instance of type javax.servlet.Servlet:

    private Servlet instance = null;

The allocate method checks if instance is null, the allocate method calls the loadServlet method to load the servlet. It then increments the countAllocated integer and returns the instance.

    if(!singleThreadModel){        //Load and initialize our instance if necessary        if(instance == null){            synchronized(this){                if(instance == null){                    try{                        instance = loadServlet();                    }catch(ServletException e){                        throw e;                    }catch(Throwable e){                        throw new ServletException(sm.getString("standardWrapper.allocate"),e);                    }                }            }        }        if(!singleThreadModel){            countAllocated++;            return instance;        }    }

If the servlet represented by StandardWrapper is a STM servlet, the allocate method attempt to return an instance from a pool. The instancePool variable of type java.util.Stack references to a stack of STM servlet instances.

    private Stack instancePool  = null;

The allocate method will allocate an instance of the STM servlet as long as the number of instances does not exceed the specified maximum number. The maxInstance integer holds the maximum number of STM instances and by default its value is 20.

    private int maxInstances = 20;

To track down the current number of STM instances, the StandardWrapper class uses the nInstance integer:

    private int nInstances = 0;

The sencod part:

    synchronized(instancePool){        while(countAllocated >= nInstances){            //Allocate a new instance if possible, or else wait              if(nInstances < maxInstances){                try{                    instancePool.push(loadServlet());                    nInstances++;                }catch(ServletException e){}                catch(Throwable e){}            }else{                try{                    instancePool.wait();                }catch(InterruptedException  e){;}            }        }        countAllocated++;        return (Servlet)instancePool.pop();    }

The code above uses a while loop to wait until nInstances is less than or equal to the value of countAllocated. Inside the while loop, the allocate method checks the value of nInstance, and if it is lower than maxInstances, the allocate method calls the loadServlet method and pushes the new instance to the pool and increments nInstances. If the number of nInstance is equal to maxInstance or greater, it waits by calling the instancePool stack’s wait method, waiting for an instance to be returned to the stack.

0 0