简介在netty中,无论是服务端的ServerBootstrap还是客户端的Bootstrap,在创建的时候都需要在group方法中传入一个EventLoopGroup参数来处理所有ServerChannel和Channel中的所有IO操作和事件。有的朋友可能稍微看过netty的源码,可能会发现有一个和EventLoopGroup很像的类,叫做EventLoop。那么EventLoopGroup和EventLoop是什么关系呢?他们的底层和通道之间的交互是什么?一起来看看吧。EventLoopGroup和EventLoopEventLoopGroup继承自EventExecutorGroup:publicinterfaceEventLoopGroupextendsEventExecutorGroup我们在上一篇文章中说过,EventExecutorGroup中有一个next方法可以返回对应的EventExecutor。在EventLoopGroup中重写了这个方法:EventLoopnext();next方法返回的不再是一个EventExecutor,而是一个EventLoop。其实EventLoop和EventLoopGroup的关系有点类似于EventExecutor和EventExecutorGroup的关系。EventLoop也是继承自EventLoopGroup,EventLoopGroup是EventLoop的集合。publicinterfaceEventLoopextendsOrderedEventExecutor,EventLoopGroup在EventLoopGroup中,除了重写的next方法外,增加了一个通道注册方法register,用于注册通道和EventLoop,实现通道和EventLoop的绑定。ChannelFutureregister(Channelchannel);InEventLoop,aparentmethodhasbeenaddedtorepresenttherelationshipbetweenEventLoopandEventLoopGroup:EventLoopGroupparent();ThedefaultimplementationofEventLoopGroupinnettyThedefaultimplementationofEventLoopGroupinnettyiscalledDefaultEventLoopGroup,firstlookatitsinheritancerelationship:IfyoureadwhatIexplainedbeforeaboutEventExecutorGroup的朋友可以看出来,DefaultEventLoopGroup和DefaultEventExecutorGroup的继承关系是很类似的,DefaultEventLoopGroup继承自MultithreadEventLoopGroup,而MultithreadEventLoopGroup又继承自MultithreadEventExecutorGroup并且实现了EventLoopGroup接口:publicabstractclassMultithreadEventLoopGroupextendsMultithreadEventExecutorGroupimplementsEventLoopGroupMultithreadEventLoopGroup是用多线程来处理EventLoop.MultithreadEventLoopGroup中定义了一个DEFAULT_EVENT_LOOP_THREADS来存储处理EventLoop线程的默认数量:DEFAULT_EVENT_LOOP_THREADS=Math.max(1,SystemPropertyUtil.getInt("io.netty.eventLoopThreads",NettyRuntime.availableProcessors()*2));对于EventLoopGroup、MultithreadEventLoopGroup中新增的几个register方法,都是通过调用对应的next方法实现的:publicChannelFutureregister(Channelchannel){returnnext().register(channel);}这里next()方法的实际实现调用的是父类的next方法,也就是MultithreadEventExecutorGroup中的next方法,用来选择Group管理的一个EventLoop:publicEventLoopnext(){return(EventLoop)超级.next();对于DefaultEventLoopGroup,它继承自MultithreadEventLoopGroup,实现了一个newChild方法,将传入的executor封装到EventLoop中:}EventLoop在netty中netty中EventLoop的默认实现叫做DefaultEventLoop,先看它的继承关系:DefaultEventLoop继承自SingleThreadEventLoop,而SingleThreadEventLoop又继承自SingleThreadEventExecutor并且实现了EventLoop接口先来看下SingleThreadEventLoop的实现:publicabstractclassSingleThreadEventLoopextendsSingleThreadEventExecutorimplementsEventLoopSingleThreadEventLoop使用单一Threadstoexecutesubmittedtasks.它和SingleThreadEventExecutor有什么区别?首先提供一个tailTask??s来存放待处理的任务:privatefinalQueuetailTask??s;这个tailTask??s会用来判断和操作任务的个数:}protectedbooleanhasTasks(){返回super.hasTasks()||!tailTask??s.isEmpty();}publicintpendingTasks(){returnsuper.pendingTasks()+tailTask??s.size();SingleThreadEventLoop中register方法的实现最终调用了注册通道中的unsaferegister方法:channel.unsafe().register(this,promise);我们再来看看DefaultEventLoop,DefaultEventLoop继承自SingleThreadEventLoop:可运行任务=takeTask();if(task!=null){task.run();updateLastExecutionTime();}if(confirmShutdown()){中断;对比一下可以发现DefaultEventLoop和DefaultEventExecutor中run方法的实现是一样的有小伙伴发现即使在最简单的netty应用中,也很少见到这两个默认的EventLoops。最常用的是NioEventLoopGroup和NioEventLoop。这是因为DefaultEventLoop和DefaultEventLoopGroup只使用了多线程技术。一个线程代表一个EventLoop。如果EventLoop过多,可能会造成线程和性能的浪费,所以在NioEventLoopGroup中使用,采用NioEventLoopNIO技术,通过使用channel、selector等NIO技术提高EventLoop的效率。关于NioEventLoopGroup和NioEventLoop的详细介绍,我们会在下一章详细讲解,敬请期待。本文已收录于http://www.flydean.com/05-1-netty-eventloop-eventloopgroup/最流行的解读,最深刻的干货,最简洁的教程,很多你不知道的小技巧等你来发现!欢迎关注我的公众号:《程序那些事儿》,懂技术,更懂你!