Tomcat 中的 NIO 源码分析
到这里,我们再回顾一下:刚刚在 PollerEvent 的 run 方法中,我们看到,新的 SocketChannel 注册到了 Poller 内部的 Selector 中,监听 OP_READ 事件,然后我们再回到 Poller 的 run 看下,一旦该 SocketChannel 是 readable 的状态,那么就会进入到 poller 的 processKey 方法。 processKey Poller # processKey protected void processKey(SelectionKey sk, NioSocketWrapper attachment) { try { if ( close ) { cancelledKey(sk); } else if ( sk.isValid && attachment != ) { if (sk.isReadable || sk.isWritable ) { // 忽略 sendfile if ( attachment.getSendfileData != ) { processSendfile(sk,attachment, false); } else { // unregister 相应的 interest set, // 如接下来是处理 SocketChannel 进来的数据,那么就不再监听该 channel 的 OP_READ 事件 unreg(sk, attachment, sk.readyOps); boolean closeSocket = false; // Read goes before write if (sk.isReadable) { // 处理读 if (!processSocket(attachment, SocketEvent.OPEN_READ, true)) { closeSocket = true; } } if (!closeSocket && sk.isWritable) { // 处理写 if (!processSocket(attachment, SocketEvent.OPEN_WRITE, true)) { closeSocket = true; } } if (closeSocket) { cancelledKey(sk); } } } } else { //invalid key cancelledKey(sk); } } catch ( CancelledKeyException ckx ) { cancelledKey(sk); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); log.error("",t); } } 接下来是 processSocket 方法,注意第三个参数,上面进来的时候是 true。 AbstractEndpoint # processSocket public boolean processSocket(SocketWrapperBase<S> socketWrapper, SocketEvent event, boolean dispatch) { try { if (socketWrapper == ) { return false; } SocketProcessorBase<S> sc = processorCache.pop; if (sc == ) { // 创建一个 SocketProcessor 的实例 sc = createSocketProcessor(socketWrapper, event); } else { sc.reset(socketWrapper, event); } Executor executor = getExecutor; if (dispatch && executor != ) { // 将任务放到之前建立的 worker 线程池中执行 executor.execute(sc); } else { sc.run; // ps: 如果 dispatch 为 false,那么就当前线程自己执行 } } catch (RejectedExecutionException ree) { getLog.warn(sm.getString("endpoint.executor.fail", socketWrapper) , ree); return false; } catch (Throwable t) { ExceptionUtils.handleThrowable(t); (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |