Netty源码剖析——分析NioEventLoopGroup 的过程(二十八)

(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 中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值