tomcat StandaedWrapper 解析
/**
* The count of allocations that are currently active (even if they
* are for the same instance, as will be true on a non-STM servlet).
*/
protected AtomicInteger countAllocated = new AtomicInteger(0);
/**
* Maximum number of STM instances.
*/
protected int maxInstances = 20;
/**
* Number of instances currently loaded for a STM servlet.
*/
protected int nInstances = 0;
/**
* Stack containing the STM instances.
*/
protected Stack<Servlet> instancePool = null;
public Servlet allocate() throws ServletException { // If we are currently unloading this servlet, throw an exception if (unloading) throw new ServletException (sm.getString("standardWrapper.unloading", getName())); boolean newInstance = false; // If not SingleThreadedModel, return the same instance every time if (!singleThreadModel) { // Load and initialize our instance if necessary if (instance == null) { synchronized (this) { if (instance == null) { try { if (log.isDebugEnabled()) log.debug("Allocating non-STM instance"); instance = loadServlet(); if (!singleThreadModel) { // For non-STM, increment here to prevent a race // condition with unload. Bug 43683, test case // #3 newInstance = true; countAllocated.incrementAndGet(); } } catch (ServletException e) { throw e; } catch (Throwable e) { ExceptionUtils.handleThrowable(e); throw new ServletException (sm.getString("standardWrapper.allocate"), e); } } } } if (!instanceInitialized) { initServlet(instance); } if (singleThreadModel) { if (newInstance) { // Have to do this outside of the sync above to prevent a // possible deadlock synchronized (instancePool) { instancePool.push(instance); nInstances++; } } } else { if (log.isTraceEnabled()) log.trace(" Returning non-STM instance"); // For new instances, count will have been incremented at the // time of creation if (!newInstance) { countAllocated.incrementAndGet(); } return (instance); } } synchronized (instancePool) { while (countAllocated.get() >= nInstances) { // Allocate a new instance if possible, or else wait if (nInstances < maxInstances) { try { instancePool.push(loadServlet()); nInstances++; } catch (ServletException e) { throw e; } catch (Throwable e) { ExceptionUtils.handleThrowable(e); throw new ServletException (sm.getString("standardWrapper.allocate"), e); } } else { try { instancePool.wait(); } catch (InterruptedException e) { // Ignore } } } if (log.isTraceEnabled()) log.trace(" Returning allocated STM instance"); countAllocated.incrementAndGet(); return instancePool.pop(); } }
/** * Return this previously allocated servlet to the pool of available * instances. If this servlet class does not implement SingleThreadModel, * no action is actually required. * * @param servlet The servlet to be returned * * @exception ServletException if a deallocation error occurs */ @Override public void deallocate(Servlet servlet) throws ServletException { // If not SingleThreadModel, no action is required if (!singleThreadModel) { countAllocated.decrementAndGet(); return; } // Unlock and free this instance synchronized (instancePool) { countAllocated.decrementAndGet(); instancePool.push(servlet); instancePool.notify(); } }

浙公网安备 33010602011771号