我们的bossgroup和workgroup都是使用的NioEventLoopGroup。其内部有一个EventExecutor类型的数组用来存储所有的线程组。
NioEventLoopGroup {
EventExecutor[] children;
}
NioEventLoopGroup继承自MultithreadEventExecutorGroup,构造函数不指定线程数默认会根据系统cpu进行计算获取。是一个线程池实现类。
在MultithreadEventExecutorGroup构造函数里初始化children。调用newChild方法创建NioEventLoop实例赋给children。EventExecutor[] children 元素实例类型是NioEventLoop。
来看下具体代码:
protected MultithreadEventExecutorGroup(int nThreads, Executor executor,
EventExecutorChooserFactory chooserFactory, Object... args) {
checkPositive(nThreads, "nThreads");
if (executor == null) {
//executor 初始化
executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
}
children = new EventExecutor[nThreads];
for (int i = 0; i < nThreads; i ++) {
boolean success = false;
try {
//newChild方法就是创建一个NioEventLoop实例,设置executor
children[i] = newChild(executor, args);
success = true;
}
}
//...
}
executor是ThreadPerTaskExecutor类型,其execute方法就是创建一个线程执行runnable参数任务。
public final class ThreadPerTaskExecutor implements Executor {
private final ThreadFactory threadFactory;
public ThreadPerTaskExecutor(ThreadFactory threadFactory) {
this.threadFactory = ObjectUtil.checkNotNull(threadFactory, "threadFactory");
}
@Override
public void execute(Runnable command) {
threadFactory.newThread(command).start();
}
}
newChild方法就是创建一个NioEventLoop实例,设置executor。
NioEventLoop是一个很重要的类,很多事件逻辑都是在该类中完成。
下面是NioEventLoop类主要方法。
NioEventLoop继承自SingleThreadEventExecutor。是一个单线程处理类。我们创建的channel都会和该类进行绑定。
主要属性
属性名 | 说明 |
---|---|
taskQueue | 任务队列,被执行的任务首先会被放到任务队列。 |
executor | 执行器,上面创建child传入ThreadPerTaskExecutor类型 |
selector | 绑定的selector |
thread | 当前EventLoop的运行线程 |
主要方法
方法 | 说明 |
---|---|
register(Channel channel) | 绑定channel |
addTask(Runnable task) | 新增一个任务到TaskQueue |
pollTask() | 取出一个任务 |
startThread() | 启动线程,会判断当前EventLoop内的线程状态,线程是否已运行,否则调用 doStartThread()启动线程 |
doStartThread() | 会调用executor.execute(Runnable)启动一个线程运行入参任务,将启动线程赋值给thread变量。入参会调用run()方法。 |
execute(Runnable task) | 执行一个任务,首先会调用addTask加入队列,然后判断是否wakeup执行线程 |
inEventLoop(Thread thread) | 判断当前线程和内部变量thread是否是同一个线程 |
runAllTasks(long timeoutNanos) | 执行任务队列里的任务 |
select(curDeadlineNanos) | 调用Selector的select方法,阻塞监听事件发生 |
processSelectedKeys(); | 处理监听到的SelectedKeys |
processSelectedKey(SelectionKey k, AbstractNioChannel ch) | 处理具体的某一key事件 |
本文含有隐藏内容,请 开通VIP 后查看