A recent desire to implement a portable thread pool is that the thread in the pool is used to process some kind of information, which can be considered an external state that the thread relies on. If implemented with a simple thread pool, threads should be initialized with some information so that the thread cannot be used again. Look at the old version of Tomcat source, found the answer, its implementation of the main idea is to use the thread of the wait and arouse, httpprocessor implementation is based on this idea, the sequence diagram as follows:
When initializing a httpprocessor thread, it is impossible to give the desired socket object, because if the socket is given during initialization, the thread cannot be recycled to handle other sockets. Therefore, in the Httpprocessor run phase, first the thread to wait, specifically in the await method embodiment, the code is as follows:
[Java] View Plain copy print? /** * await a newly assigned socket from our connector, or <code>null</code> * if we are supposed to shut down. */ private synchronized socket await () { // wait for the connector to provide a new socket while (!available) { try { wait (); } catch (interruptedexception e) { } } // notify&nbsP;the connector that we have received this socket Socket socket = this.socket; available = false; notifyall (); if ((debug >= 1) && (socket != null)) log (" The incoming request has been awaited "); return (socket); } /** * Await A newly assigned Socket from my Connector, or <code>null</code> * if we are supposed to sh UT down. * Private synchronized socket await () {//wait for the Connector to provide a new Socket while (!available) {try {wait (); The catch (Interruptedexception e) {}}//Notify The Connector that we have received This socket socket = This.socket; Available = false; Notifyall (); if (debug >= 1) && (socket!= null) log ("The incoming request has been awaited"); return (socket); }
When HttpConnector calls the Httpprocessor.assign (socket) method, the thread is given the socket object and the thread is invoked to continue execution, and the source code for the Assign method is as follows:
[Java] View Plain copy print? /** * Process an incoming TCP/IP connection on the specified socket. any * exception that occurs during processing must be logged and swallowed. * <b>note</b>: this method is called from our connector ' s thread. we * must assign it to our own thread so that multiple simultaneous * requests can be handled. * * @param socket TCP socket to process */ synchronized Void assign (socket socket) { // Wait For the processor to get the previous socket while (available) { try { wait (); } catch (interruptedexception e) { } } // Store the newly available Socket and Notify our thread this.socket = socket; available = true; notifyall (); if ((debug >= 1) && (socket != null) log (" an incoming request is being assigned "); } /** * Process an incoming TCP/IP connection on the Specifi Ed socket. Any * exception that occurs during processing must is logged and swallowed. * <B>NOTE</B>: This is the called from our Connector ' s thread. We * Must assign it to my own thread so, multiple simultaneous * requests can be handled. * * @param socket TCP socket to process/synchronized void assign (socket sockets) {//wait for the Processor to get the Previous Socket while (available) {try {wait ();} catch (Interruptedexception e) {}}/Store the newly available sock ET and notify our thread this.socket = socket; Available = true; Notifyall (); if (debug >= 1) && (socket!= null) log ("A incoming request is being assigned"); }
After the thread is aroused and given the socket object, continue to execute the core process method, Httpprocessor.run the complete source code as follows:
[Java] View Plain copy print? /** * the background thread that listens for incoming tcp/ ip connections and * hands them off to an appropriate processor. */ public void run () { // process requests until we receive a shutdown signal while (!stopped) { // Wait for the next socket to be Assigned socket socket = await (); if (socket == null) continue; // process the request from this socket try { process (socket); } catch (throwable t) { log ("Process.invoke", t); } // finish up this request Connector.recycle (This); } // tell threadstop () we have shut ourselves down Successfully &NBSP;&Nbsp; synchronized (threadsync) { threadsync.notifyall (); } } /** * the Background thread that listens for incoming TCP/IP connections and * hands them off to a appropriate. */public void Run () {//Process requests until we receive a shutdown signal while (!stopped) {//wait for the next sock ET to is assigned socket socket = await (); if (socket = = NULL) continue; Process the request from this socket try {process (socket);} catch (Throwable t) {log ("Process.invoke", t);}//Fini SH up this request connector.recycle (this); }//Tell Threadstop () We have shut ourselves down successfully synchronized (Threadsync) {Threadsync.notifyall ();}}