APR是Apache可移植运行库(Apache portable Run-time libraries)的简称,这是一个可以跨越多操作系统平台使用的底层支持接口库.在Tomcat的实现中就有使用该库的地方,AprEndpoint就是将Socket方面的操作直接用JNI替代而非Java元素的API.这使得其有较高的性能要求.同样AprEndpoint也是继承了AbstractEndpoint在实现的具体细节有点差别而已.只是另一种JIoEndpoint.提供了Acceptor线程,Socket轮询线程,Worker线程池和文件发送线程.
先看看Acceptor的实现.于JIoEndpoint有着极其相似的代码结构.
public void run() { int errorDelay = 0; // Loop until we receive a shutdown command while (running) { // Loop if endpoint is paused while (paused && running) { state = AcceptorState.PAUSED; try { Thread.sleep(50); } catch (InterruptedException e) { // Ignore } } if (!running) { break; } state = AcceptorState.RUNNING; try { //if we have reached max connections, wait countUpOrAwaitConnection(); long socket = 0; try { // Accept the next incoming connection from the server // socket socket = Socket.accept(serverSock); } catch (Exception e) { //we didn't get a socket countDownConnection(); // Introduce delay if necessary errorDelay = handleExceptionWithDelay(errorDelay); // re-throw throw e; } // Successful accept, reset the error delay errorDelay = 0; if (running && !paused) { // Hand this socket off to an appropriate processor if (!processSocketWithOptions(socket)) { // Close socket and pool right away destroySocket(socket); } } else { // Close socket and pool right away destroySocket(socket); } } catch (Throwable t) { .... } // The processor will recycle itself when it finishes } state = AcceptorState.ENDED; }
其中的socket = Socket.accept(serverSocket)就是使用的JNI,也就是APR库.而这个类的所有Socket的实现也是使用该库的.至于其他线程也是使用了该库.看下生命周期的bind方法的部分代码,里面用了更多的APR的函数.大体的内容也是一致的.只是在Socket实现的API不一样而已.至于NIoEndpoint也是类似的实现.只不过实现方式是ServerSockeChannel,SockeChannel和Selector的就绪选择.