1.NioEventLoop概述
3个问题:
1.默认情况下,Netty服务端起多少线程?何时启动?
2.Netty是如何解决jdk空轮询bug的?
3.Netty如何保证异步串行无锁化?
创建-----启动----执行逻辑
2.NioEventLoop创建概述
new NioEventLoopGroup()[线程组,默认2*cpu]
new ThreadPerTaskExecutor()[线程创建器]
for(){newChild()}[构造NioEventLoop]
chooserFactory.newChooser()[线程选择器]
3.ThreadPerTaskExecutor
executor = new ThreadPerTaskExecutor(this.newDefaultThreadFactory());
1.每次执行任务都会创建一个线程实体
2.NioEventLoop线程命名规则nioEventLoop-1-xx
4.创建NioEventLoop线程
this.children[i] = this.newChild((Executor)executor, args);
return new NioEventLoop(this, executor, selectorProvider, selectStrategyFactory.newSelectStrategy(), rejectedExecutionHandler, taskQueueFactory, tailTaskQueueFactory);
1.保存线程执行器ThreadPerTaskExecutor
2.创建一个MpscQueue
3.创建一个selector
5.创建线程选择器
this.chooser = chooserFactory.newChooser(this.children);
chooserFactory.newChooser()
isPowerOfTwo() 判断是否是2的幂,如2,4,8,16
PowerOfTwoEventExecutorChooser[优化]
index++ & (length-1)
GenericEventExecutorChooser[普通]
abs(index++%length)
6.NioEventLoop的启动
1.服务端启动绑定端口
bind()----execute(task)[入口]
startThread->doStartThread[创建线程]
ThreadPerTaskExecutor.execute()
thread = Thread.currentThread()
NioEventLoop.run()[启动]
2.新连接接入通过chooser绑定一个NioEventLoop
7.NioEventLoop执行概述
SingleThreadEventExecutor.this.run()
run()—>for(;😉
select()[检查是否有io事件]
processSelectedKeys()[处理IO事件]
runAllTasks()[处理异步任务队列]
8.检测IO事件
select方法执行逻辑:
1.deadline以及任务穿插逻辑处理
2.阻塞式select
3.避免JDK空轮询的bug
9.处理IO事件
processSelectedKey()执行逻辑:
1.selected keySet 优化
2.processSelectedKeysOptimized()
10.reactor线程任务的执行
普通任务 + 定时任务
runAllTasks()执行逻辑:
1.task的分类和添加
2.任务的聚合
3.任务的执行