(1)构造器方法
public NioEventLoopGroup(int nThreads) {
this(nThreads, null);
}
(2)上面的this(nThreads,(Executor) null); 调用构造器 (通过 alt+d 看即可)
public NioEventLoopGroup(int nThreads, ThreadFactory threadFactory) {
this(nThreads, threadFactory, SelectorProvider.provider());
}
(3)上面的 this(nThreads, executor SelectorProvider provider(); 调用下面构造器
public NioEventLoopGroup(
int nThreads, ThreadFactory threadFactory, final SelectorProvider selectorProvider) {
this(nThreads, threadFactory, selectorProvider, DefaultSelectStrategyFactory.INSTANCE);
}
(4)上面的 this ().调用构造器(alt+d)
public NioEventLoopGroup(int nThreads, ThreadFactory threadFactory,
final SelectorProvider selectorProvider, final SelectStrategyFactory selectStrategyFactory) {
super(nThreads, threadFactory, selectorProvider, selectStrategyFactory, RejectedExecutionHandlers.reject());
}
(5)上面的 super().. 的方法 是父类: MultithreadEventLoopGroup
protected MultithreadEventLoopGroup(int nThreads, ThreadFactory threadFactory, Object... args) {
super(nThreads == 0? DEFAULT_EVENT_LOOP_THREADS : nThreads, threadFactory, args);
}
(6)追踪到源码抽象类MultithreadEventExecutorGroup的构造器方法 MultithreadEventExecutorGroup才是NioEventLoopGroup 真正的构造方法, 这里可以看成是一个模板方法(设计模式),所以,我们就需要好好分析 MultithreadEventExecutorGroup 方法了
(7)分析 MultithreadEventExecutorGroup
(8)参数分析
* @param nThreads 使用的线程数,默认为 core *2 [可以追踪源码]
* @param executor 执行器:如果传入 null,则采用 Netty 默认的线程工厂和默认的执行器 ThreadPerTaskExecutor
@param chooserFactory 单例 new DefaultEventExecutorChooserFactory()
@param args args 在创建执行器的时候传入固定参数
protected MultithreadEventExecutorGroup(int nThreads,Executor executor,
EventExecutorChooserFactory chooserFactory,Object...args){
if(nThreads<=0){//
throw new Illegal ArgumentException(String.format("nThreads:%d(expected:>0)",nThreads));
if(executor=null){//如果传入的执行器是空的则采用默认的线程工厂和默认的执行器
executor=new ThreadPerTaskExecutor(newDefaultThrcadFactory);
//创建指定线程数的执行器数组
children=newEventExecutor(nThreads];
//初始化线程数组
for(inti=0;i<nThreads;i++){
boolean success=false;
try{
//创建new NioEventLoop
children[i]=newChild(executor,args);
success=true;
}catch(Exception e){
//TODO:Think about ifthis is a good exception type
throw new lllegalStateException("failed to create a child event loop",e);
}finally{
//如果创建失败,优雅关闭
if(!success){
for(intj=0;j<i;j++){
children[j].shutdownGracefully();
}
for(intj=0;j<i;j++){
EventExecutore=children[j]
try{
while(!e.isTerminated){
e.await Termination(Integer.MAX_VALUE,TimeUnit.SECONDS);
}catch(InterruptedException interrupted){
//Let the caller handle the interruption.
Thread.currentThread().interruptO;
break;
}
}
}
}
}
chooser=chooserFactory.newChooser(children);
final FutureListener<Object>terminationlistener=new FutureListener<Object>(){
@Override
public void operationComplete(Future<Object>future)throwsException{
if(terminatedChildren,incrementAndGet()==children.length){
terminationFuture.setSuccess(null);
}
}
};
//为每一个单例线程池添加一个关闭监听器
for(EventExecutor e:children){
e.terminationFuture().addListener(terminationListener);
}
Set<EventExecutor>childrenSet=newLinkedHashSet<EventExecutor>(children.length);
//将所有的单例线程池添加到一个 HashSet 中。
Collections.addAll(childrenSet,children);
readonly Children=Collections.unmodifiableSct(childrenSct);
}
解释说明
1)如果 executor是null,创建一个默认的ThreadPerTaskExecutor,使用Netty默认的线程工厂。
2)根据传入的线程数(CPU*2)创建一个线程池(单例线程池)数组。
3)循环填充数组中的元素。如果异常,则关闭所有的单例线程池。
4)根据线程选择工厂创建一个线程选择器。
5)为每一个单例线程池添加一个关闭监听器。
6)将所有的单例线程池添加到一个 HashSet 中。