NioEventLoopGroup初始化
以Netty 4.1.24.Final为例
由于服务端和客户端都会创建NioEventLoopGroup对象,因此单独提取出来。进入NioEventLoopGroup无参构造方法,定位父类MultithreadEventLoopGroup。
public abstract class MultithreadEventLoopGroup extends MultithreadEventExecutorGroup implements EventLoopGroup { private static final InternalLogger logger = InternalLoggerFactory.getInstance(MultithreadEventLoopGroup.class); private static final int DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2)); protected MultithreadEventLoopGroup(int nThreads, Executor executor, Object... args) { super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, args); }
如果io.netty.eventLoopThreads未设置,初始线程数默认是处理器的2倍。
protected MultithreadEventExecutorGroup(int nThreads, Executor executor, EventExecutorChooserFactory chooserFactory, Object... args) { this.terminatedChildren = new AtomicInteger(); this.terminationFuture = new DefaultPromise(GlobalEventExecutor.INSTANCE); if (nThreads <= 0) { throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads)); } else { if (executor == null) { executor = new ThreadPerTaskExecutor(this.newDefaultThreadFactory()); } this.children = new EventExecutor[nThreads]; int j; for(int i = 0; i < nThreads; ++i) { boolean success = false; boolean var18 = false; try { var18 = true; this.children[i] = this.newChild((Executor)executor, args); success = true; var18 = false; } catch (Exception var19) {
在MultithreadEventExecutorGroup构造方法中,初始并实例化了children数组。
protected EventLoop newChild(Executor executor, Object... args) throws Exception { return new NioEventLoop(this, executor, (SelectorProvider)args[0], ((SelectStrategyFactory)args[1]).newSelectStrategy(), (RejectedExecutionHandler)args[2]); }
进入this.newChild方法,实例化NioEventLoop对象,可见children数组的存储的实例就是NioEventLoop。
NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider, SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler) { super(parent, executor, false, DEFAULT_MAX_PENDING_TASKS, rejectedExecutionHandler); if (selectorProvider == null) { throw new NullPointerException("selectorProvider"); } else if (strategy == null) { throw new NullPointerException("selectStrategy"); } else { this.provider = selectorProvider; NioEventLoop.SelectorTuple selectorTuple = this.openSelector(); this.selector = selectorTuple.selector; this.unwrappedSelector = selectorTuple.unwrappedSelector; this.selectStrategy = strategy; } }
NioEventLoop super方法由父类SingleThreadEventLoop实例化,并且创建了一个LinkedBlockingQueue队列
protected SingleThreadEventLoop(EventLoopGroup parent, Executor executor, boolean addTaskWakesUp, int maxPendingTasks, RejectedExecutionHandler rejectedExecutionHandler) { super(parent, executor, addTaskWakesUp, maxPendingTasks, rejectedExecutionHandler); this.tailTasks = this.newTaskQueue(maxPendingTasks); }
另外在NioEventLoop创建时还会打开一个Selector,并将该Selector绑定到该线程上,NioEventLoop初始化完成。关于Selector实现原理可以看Selector实现原理
this.provider = selectorProvider; NioEventLoop.SelectorTuple selectorTuple = this.openSelector();
再回到MultithreadEventExecutorGroup,定位chooser,看方法名应该用来是创建chooser,进入。
this.chooser = chooserFactory.newChooser(this.children);
public EventExecutorChooser newChooser(EventExecutor[] executors) { return (EventExecutorChooser)(isPowerOfTwo(executors.length) ? new DefaultEventExecutorChooserFactory.PowerOfTwoEventExecutorChooser(executors) : new DefaultEventExecutorChooserFactory.GenericEventExecutorChooser(executors)); }
如果传入的数组大小是2的指数倍,创建PowerOfTwoEventExecutorChooser对象,否则创建GenericEventExecutorChooser。