代码结构:
三步走结构:
总调度者(线程管理者):
NioSelectorRunnablePool 管理worker 和 boss线程池
NioSelectorRunnablePool 会初始化 一个执行worker任务的线程池和 一个执行boss任务的线程池,并且负责把worker(NioServerWorker) 和boss(NioServerBoss)调度处来工作,NioServerWorker和 NioServerBoss 本质是Runnable(线程任务)。
NioServerWorker、NioServerBoss被初始化的时候(实际是调用父类的构造方法AbstractNioSelector):
1、把AbstractNioSelector 也会在构造方法中私有化,AbstractNioSelector 实现了Runnable
2、会把worker线程和boss线程在构造方法中私有化,worker任务和boss任务会被扔进这个 线程池去执行
3、openSelector:会打开一个selecor,selecor属于NioServerBoss和NioServerWorker
boss、bosses、NioServerBoss:
boss是线程池,bosses 是 NioServerBoss 数组 ,NioServerBoss是真正工作的管家NioServerBoss继承于AbstractNioSelector,并且实现了boss接口,初始化的时候会初始bosses数组,把NioServerBoss扔进bosses数组,把boss扔进NioServerBoss,boss线程池会调度处理NioServerBoss。
worker、workeres、NioServerWorker:
worker是线程池,workeres 是 NioServerWorker数组 ,NioServerWorker是真正工作的工人。
NioServerWorker继承于AbstractNioSelector,并且实现了Worker接口 初始化的时候会初始workeres数组,把NioServerWorker扔进workeres数组,把 worker扔进NioServerWorker,worker线程池会调度处理NioServerWorker
ServerBootstrap:
实例化ServerBootstrap,并绑定端口,开启一个ServerSocketChannel 通道。利用NioSelectorRunnablePool.nextBoss() 调度出一个管家,在此Boss上注册该服务通道,Boss会调度该服务通道,再把初始化的时候开启的一个selector 给到该服务通道,服务通道通过seletor管理连接进来的客户端。为了实现 异步,此处的selector和ServerSocketChannel以及OP_ACCEPT事件绑定被放进了一个Runnable里面,Runnable会做为一个task被放进一个queue里面,等待接下来的被消费。
抽象selector线程(AbstractNioSelectocr):
AbstractNioSelector在初始化的时候(也就是 NioServerWorker或者NioServerBoss初始化的时候)会开启一个selector,并且在开启selector的时候,把 该实例化的AbstractNioSelector(NioServerWorker或者NioServerBoss)扔进线程池,同时AbstractNioSelector其实也是一个Runnable,里面的run方法调 用了,select、processTaskQueue、process。processTaskQueue是从taskQueue里面取任务,taskQueue里面取出来的是selector和ServerSocketChannel 以及某事件绑定的Runnable,select 子类实现,取出来连接的客户端。
process子类实现:
Boss实现:取出来连接的客户端,并利用NioSelectorRunnablePool调用出Worker来实际解决问题
Worker实现:处理真正的业务逻辑
第一层结构:
负责管理Worker、Boss 的线程池
利用NioSelectorRunnablePool调度出Worker、Boss,然后把Worker、Boss扔进线程池调度,而自己的run方法里面实现了第二层的异步。
第二层结构:
Worker、Boss开启一个线程负责管理Selector、ServerSocketChannel和事件绑定,并且把该线程扔进队列,等待下次消费,Worker、Boss开启的run方法消费到该task,就开启第三层异步调用。
第三层结构:
Boss 利用非堵塞的selector,select出来一个客户端,并且利用NioSelectorRunnablePool调度出一个Worker,然后把客户端扔给Worker去解决真正的问题。
网友评论