NioEventLoop实现
本文最后更新于 2024年6月24日 晚上
在Netty中,NioEventLoop主要任务为绑定Channel并对Channel的IO事件进行监听。本文中所有内容均来自Netty 4.1.89.Final。
继承关系
classDiagram
direction BT
class AbstractEventExecutor
class AbstractExecutorService
class AbstractScheduledEventExecutor
class EventExecutor {
<<Interface>>
}
class EventExecutorGroup {
<<Interface>>
}
class EventLoop {
<<Interface>>
}
class EventLoopGroup {
<<Interface>>
}
class Executor {
<<Interface>>
}
class ExecutorService {
<<Interface>>
}
class Iterable~T~ {
<<Interface>>
}
class NioEventLoop
class OrderedEventExecutor {
<<Interface>>
}
class ScheduledExecutorService {
<<Interface>>
}
class SingleThreadEventExecutor
class SingleThreadEventLoop
AbstractEventExecutor --> AbstractExecutorService
AbstractEventExecutor ..> EventExecutor
AbstractExecutorService ..> ExecutorService
AbstractScheduledEventExecutor --> AbstractEventExecutor
EventExecutor --> EventExecutorGroup
EventExecutorGroup --> Iterable~T~
EventExecutorGroup --> ScheduledExecutorService
EventLoop --> EventLoopGroup
EventLoop --> OrderedEventExecutor
EventLoopGroup --> EventExecutorGroup
ExecutorService --> Executor
NioEventLoop --> SingleThreadEventLoop
OrderedEventExecutor --> EventExecutor
ScheduledExecutorService --> ExecutorService
SingleThreadEventExecutor --> AbstractScheduledEventExecutor
SingleThreadEventExecutor ..> OrderedEventExecutor
SingleThreadEventLoop ..> EventLoop
SingleThreadEventLoop --> SingleThreadEventExecutor
NioEventLoop的继承树非常复杂,一侧为接口继承关系,一侧为实现类继承关系。
接口继承关系
Executor接口来自于java.util.concurrent包,声明了execute(Runnable command)方法。ExecutorService接口来自于java.util.concurrent包,增加了关闭方法、提交Runnable和Callable执行方法。ScheduledExecutorService接口来自于java.util.concurrent包,增加了定时执行任务的schedule方法。Iterable接口来自于java.lang包,增加了forEach和iterator方法。EventExecutorGroup接口来自于io.netty.util.concurrent包,添加了shutdownGracefully方法和next方法,并废弃了继承自ExecutorService的关闭方法。EventExecutor接口来自于io.netty.util.concurrent包,添加了inEventLoop()方法。这里有一些有意思的事情:
EventExecutor继承了EventExecutorGroup的next接口,对于单个执行器而言,next只会返回自身,接口本身是不存在意义的。Netty之所以没有直接继承ScheduledExecutorService接口,可能是源自于对shutdownGracefully方法的需求。OrderedEventExecutor接口来自于io.netty.util.concurrent包,没有增加任何方法。EventLoopGroup接口来自于io.netty.channel包,增加了register方法,并引入了Channel的依赖。Netty的继承设计的非常巧妙,其中关于
next函数的重写如下:EventExecutorGroup中next函数的声明如下:1
EventExecutor next();EventLoopGroup中将next函数重写如下:1
2@Override
EventLoop next();其中
EventLoop继承自EventExecutor,在EventLoopGroup退化为EventExecutorGroup使用时,返回EventExecutor,其方法仍然符合预期,满足里氏替换原则。EventLoop接口来自于io.netty.channel,继承自OrderedEventExecutor和EventLoopGroup接口,增加了parent方法,返回EventLoopGroup。
实现类继承关系
AbstractExecutorService抽象类来自于java.util.concurrent包,实现了ExecutorService接口。AbstractEventExecutor抽象类来自于io.netty.util.concurrent包,实现了EventExecutor接口。主要实现了submit,shutdownGracefully,schedule,inEventLoop,next等方法。AbstractScheduledEventExecutor抽象类来自于io.netty.util.concurrent包,创建了优先级队列,对schedule方法提供支持。SingleThreadEventExecutor抽象类来自于io.netty.util.concurrent包,创建了Runnable阻塞队列,并对AbstractScheduledEventExecutor中的方法进一步封装。虽然引入了Thread变量,实际上Thread与子类传入的Executor所使用的线程时一致,通过封装execute函数,将传入Runnable放入队列中执行。SingleThreadEventLoop抽象类来自于io.netty.channel包,实现了EventLoop接口,增加了register方法,该类仍然没有构建线程,也不存在线程的具体处理逻辑。NioEventLoop类来自于io.netty.channel.nio包,实现了线程处理逻辑的run方法,重载了register方法,支持设置IORatio。
总结
NioEventLoop主要可以实现定时任务schedule,实时任务execute,IO事件处理register。其中单个NioEventLoop可以注册多个Channel,但是单个Channel只可以绑定单一NioEventLoop。