版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在页面明显位置给出原文链接。 https://blog.csdn.net/mengxiangqihangz/article/details/88430828
文章目录
下面是Server容器部分模型。
Nio请求重点关注黑框中的部分。
对象结构是 connect对象中包含了一个protocolHandler[Http11NioProtocol] 的实例。
protocolHandler[Http11NioProtocol] 中包含了 endpoint[NioEndPoint] 实例
endpoint[NioEndPoint] 包含了
线程Acceptor[] acceptors 【由Accept 构成的线程】
线程Poller[] pollers 【由Poller 构成的线程】
线程Executor executor 【执行SocketProcessor 任务】
监听ServerSocketChannel的线程 【Acceptor线程】
此线程主要是监听连接请求,将请求封装好,丢到任务队列中
- Acceptor 类的run()
- setSocketOptions ()
至于为什么要对 SocketChannel 重新封装,容后说明
- 上面的 register()
至于为什么要 封装一个KeyAttachment对象,也容后再说明
每个Poller 线程对象,都有自己的events队列,这里要注意,后续理解要用
查看并发代码的时候,一旦将任务丢到了队列中,通常意味着将有另外的线程会对任务进行处理
===》到此Accept线程任务差不多完成了
下一步的思路是,既然有入队列,那么肯定有出队列消费。根据出队列,反向查找那条线程再消费
处理待注册的NioChannel 的Poller[] pollers 线程
此线程的任务是将Accept线程丢到队列events中的NioChannel 注册到Selector(只监听读)中,然后监听Selector,并处理其选择的SelectionKey
- run方法
一、 注册到Selector
二、处理SelectionKey
- 处理NioChannel
- processSocket()
有线程池,交给线程池执行SocketProcessor,没有则本线程调用 SocketProcessor 的run方法
===》 差不多该线程结束
线程Executor executor
** 主要任务读取NioChannel中的数据**
- run()
- doRun()
建议跳到头部看一下,此处是交由其上级容器,即protocolHandler处理
- ** 交由Http11NioProtocol$Http11ConnectionHandler 的process方法处理**
创建的processor 为 Http11NioProcessor (上面的叫protocolHandler 协议处理器)
由Http11NioProcessor 处理wrapper(KeyAttachment基础了SocketWrapper)
- Http11NioProcessor 的process方法,实为其父类AbstractHttp11Processor 中的方法
–》 至此开始真正的读取channel中的数据
挺长的转下一篇吧