书接上文。
当Tomcat的Acceptor监听到有请求到来时,就会结束阻塞,继续进行程序下面的动作。如下面的代码所示:
- public void run() {
- while (running) {
- while (paused) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
- }
- try {
- // 开始监听端口
- Socket socket = serverSocketFactory.acceptSocket(serverSocket);
- // 初始化Socket
- serverSocketFactory.initSocket(socket);
- // 处理Socket
- if (!processSocket(socket)) {
- try {
- socket.close();
- } catch (IOException e) {
- }
- }
- } catch (IOException x) {
- if (running)
- log.error(sm.getString("endpoint.accept.fail"), x);
- } catch (Throwable t) {
- log.error(sm.getString("endpoint.accept.fail"), t);
- }
- }
- }
结束阻塞后,首先是Socket的初始化,由于ServerSocketFactory的实现类DefaultServerSocketFactory并没有扩展initSocket()方法,所以这一步其实是什么都没做的。
接下来程序执行到了processSocket(socket);这一步了,这个方法的源代码如下所示:
- protected boolean processSocket(Socket socket) {
- try {
- if (executor == null) {
- // 得到一个Work并为它分配这个Socket
- getWorkerThread().assign(socket);
- } else {
- executor.execute(new SocketProcessor(socket));
- }
- } catch (Throwable t) {
- log.error(sm.getString("endpoint.process.fail"), t);
- return false;
- }
- return true;
- }
executor是一个外部的基于线程池的执行器,先不去考虑它,重点看一下getWorkerThread()和Worker#assign()
getWorkerThread()的源代码如下:
- protected Worker getWorkerThread() {
- // 获取一个Worker
- Worker workerThread = createWorkerThread();
- while (workerThread == null) {// 如果获取的Worker为Null
- try {
- synchronized (workers) {
- // 等待workers里边Worker的回收,recycleWorkerThread()中会调用notify通知这个线程结束等待的
- workers.wait();
- }
- } catch (InterruptedException e) {
- }
- // 等待结束,再次获取一个Worker
- workerThread = createWorkerThread();
- }
- return workerThread;
- }
这里这个createWorkerThread()也就是获取Worker的方法值得研究一下。
- protected Worker createWorkerThread() {
- synchronized (workers) {
- if (workers.size() > 0) {// 如果堆栈中有剩余的Worker
- // 当前在使用的Worker线程计数
- curThreadsBusy++;
- // 将一个Worker推出堆栈
- return workers.pop();
- }
- // 如果堆栈中没有多余的Worker了,那么创建一个。
- if ((maxThreads > 0) && (curThreads < maxThreads)) {
- // 如果maxThreads有定义,并且当前的Worker数量小于这个值。
- // 在recycleWorkerThread()中会将新创建的Worker放入堆栈的
- curThreadsBusy++;
- return (newWorkerThread());
- } else {
- if (maxThreads < 0) {
- // maxThreads没有定义,可以有无限个Worker的情况。
- curThreadsBusy++;
- return (newWorkerThread());
- } else {
- return (null);
- }
- }
- }
- }
而newWorkerThread()方法还是很好理解的:
- protected Worker newWorkerThread() {
- Worker workerThread = new Worker();
- workerThread.start();
- return (workerThread);
- }
创建一个Worker线程,并且开启线程。
经过上述的过程,就获得了一个Worker(并且已经开始运行了),那么程序的下一步是调用Worker的assign()方法:
- synchronized void assign(Socket socket) {
- // 等待获取完上一个Socket
- while (available) {
- try {
- wait();
- } catch (InterruptedException e) {
- }
- }
- // 保存新的Socket
- this.socket = socket;
- available = true;
- notifyAll();
- }
这样新的Worker已经有一个Socket对象去处理了,下面来看一下Worker的线程中做了哪些工作。
- public void run() {
- // 知道收到停止信号,否则一直循环
- while (running) {
- // 等待为这个线程设置一个Socket对象
- Socket socket = await();
- if (socket == null)
- continue;
- // 处理请求
- if (!setSocketOptions(socket) || !handler.process(socket)) {
- // 关闭Socket
- try {
- socket.close();
- } catch (IOException e) {
- }
- }
- // 回收Worker
- socket = null;
- recycleWorkerThread(this);
- }
- }
其中await()用于等待有Socket对象赋给当前的Worker已进行请求处理,代码如下:
- private synchronized Socket await() {
- // 等待获取Socket
- while (!available) {
- try {
- wait();
- } catch (InterruptedException e) {
- }
- }
- // Socket已经收到
- Socket socket = this.socket;
- available = false;
- // 这个notifyAll()是通知assign()中的等待Socket的处理已经开始了,
- // 可以为这个Worker赋新的值了。
- notifyAll();
- return (socket);
- }
而setSocketOptions()用于设定一些Socket的参数,如下所示:
- protected boolean setSocketOptions(Socket socket) {
- int step = 1;
- try {
- if (soLinger >= 0) {
- socket.setSoLinger(true, soLinger);
- }
- if (tcpNoDelay) {
- socket.setTcpNoDelay(tcpNoDelay);
- }
- if (soTimeout > 0) {
- socket.setSoTimeout(soTimeout);
- }
- step = 2;
- serverSocketFactory.handshake(socket);
- } catch (Throwable t) {
- if (log.isDebugEnabled()) {
- if (step == 2) {
- log.debug(sm.getString("endpoint.err.handshake"), t);
- } else {
- log.debug(sm.getString("endpoint.err.unexpected"), t);
- }
- }
- return false;
- }
- return true;
- }
handler.process(socket)封装了处理请求的全过程,下次再详细了解
而最后的recycleWorkerThread()用于回收Worker到堆栈中以备下次使用:
- protected void recycleWorkerThread(Worker workerThread) {
- synchronized (workers) {
- workers.push(workerThread);
- curThreadsBusy--;
- workers.notify();
- }
- }
好了,请求处理的整个流程大致就是这样的,下次再详细了解请求的真实处理部分,就是handler.process(socket)的内容。