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
。