加入收藏 | 设为首页 | 会员中心 | 我要投稿 晋中站长网 (https://www.0354zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 系统 > 正文

Tomcat 中的 NIO 源码分析

发布时间:2020-01-08 14:13:19 所属栏目:系统 来源:站长网
导读:副标题#e# 虽然本文的源码篇幅也不短,但是 Tomcat 的源码毕竟不像 Doug Lea 的并发源码那么变态,对于大部分读者来说,阅读难度比之前介绍的其他并发源码要简单一些,所以读者不要觉得有什么压力。 本文基于 Tomcat 当前(2018-03-20)最新版本 9.0.6。 先简

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

(编辑:晋中站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读