Recently, you want to implement a thread pool that is portable, where the thread in the pool is being used to process some kind of information that can be considered as the external state on which the thread depends. If implemented with a simple thread pool, some information is given when the thread is initialized, so that the thread cannot be reused. In looking at the old version of Tomcat source, found the answer, the realization of the main idea is to take advantage of the thread waiting and recall, httpprocessor implementation is based on this idea, the timing diagram is as follows:
When initializing the httpprocessor thread, it is not able to give the desired socket object, because if it is given to the socket during the initialization phase, the thread cannot be recycled to handle the other sockets. Therefore, in the run phase of httpprocessor, the thread is first given to wait, which is embodied in the await method, as shown in the following code:
[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 our Connector, or <code>null</code> * if we is supposed to sh UT down. */private synchronized socket await () {//Wait for the Connector to provide a new socket while (!available) {try {Wait (); } catch (Interruptedexception e) {}}//Notify The Connector, 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); }
When HttpConnector calls the Httpprocessor.assign (socket) method, it assigns the socket object to the thread and invokes the thread so that it continues 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 this occurs during processing must be logged and swallowed. * <B>NOTE</B>: This method was called from our Connector ' s thread. We * Must assign it to our own thread so this 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 Sock ET and notify our thread this.socket = socket; Available = true; Notifyall (); if (debug >= 1) && (socket! = NULL)) log ("an incoming request is being assigned"); }
After the thread is aroused and given the socket object, continue executing the core process method, the full source of the Httpprocessor.run is 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 This 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 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 had shut ourselves down successfully synchronized (Threadsync) {Threadsync.notifyall ();}}