NioEventLoop以及NioEventLoopGroup的继承结构如下:
一般Netty中通过调用NioEventLoopGroup(int nThreads)方法构造一个并NioEventLoopGroup并随之创建多个NioEventLoop同时存在对应的数组之中,其中需要注意的细节如下:
- 在NioEventLoopGroup(int nThreads)初始化方法中实际上会使用多个默认类型实例,如:
- Executor实际为ThreadPerTaskExecutor实例,最终的NioEventLoop绑定的线程就是通过ThreadPerTaskExecutor生成的,其底层就是对于每次调用execute方法简单地创建一个Thread并start
- SelectorProvider实际为SelectorProvider.provider()实例
- SelectStrategyFactory实际为DefaultSelectStrategyFactory.INSTANCE实例
- NioEventLoop的创建是通过NioEventLoop覆写的newChild方法实现的,当NioEventLoop被创建的时候,其对应的线程还没有启动甚至都没有绑定,线程是在添加第一个任务的时候才被创建并执行的(通过调用NioEventLoop的Executor的execute方法),也即在NioEventLoop在调用execute方法的时候,该方法会先判断当前执行线程是否是绑定的线程,如果是的话则将Task放入等待队列,反之则先执行doStartThread方法,doStartThread会先判断当前EventLoop是否已经启动,如果没有则会先调用状态Updater的compareAndSet原子操作完成状态的修改(防止并发造成创建多个线程),然后再将调用NioEventLoop的run方法的过程封装成一个Runnable作为参数并调用内部执行器executor(ThreadPerTaskExecutor)的execute方法,executor在每次执行exectue方法的时候都会通过DefaultThreadFactory创建一个新的线程去执行对应的Runnable,而封装的Runnable块中再调用NioEventLoop的run方法前会先通过thread=Thread.currentThread()将创建的新的线程绑定到NioEventLoop上,从而完成了NioEventLoop和线程的一对一绑定以及启动