设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 数据 手机
当前位置: 首页 > 服务器 > 系统 > 正文

Tomcat 中的 NIO 源码分析(12)

发布时间:2020-01-07 12:09 所属栏目:52 来源:站长网
导读:到这里,我们再回顾一下:刚刚在 PollerEvent 的 run 方法中,我们看到,新的 SocketChannel 注册到了 Poller 内部的 Selector 中,监听 OP_READ 事件,然后我们再回到 Poller 的 run 看下,一旦该 SocketChannel

到这里,我们再回顾一下:刚刚在 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); 

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读