程序猿之路

Netty源码分析(六)EventLoopGroup

2017-05-25  本文已影响86人  三斤牛肉

EventLoopGroup包含了EventLoop的一个数组

private final EventExecutor[] children;

protected MultithreadEventExecutorGroup(int nThreads, Executor executor,EventExecutorChooserFactory chooserFactory, Object... args) {
  children = new EventExecutor[nThreads];
  for (int i = 0; i < nThreads; i ++) {
    boolean success = false;
    try {
      children[i] = newChild(executor, args);//创建一组EventLoop
      success = true;
    } catch (Exception e) {
               ...
    } finally {
                ...
    }
  }
}

核心函数

//创建一个NioEventLoop
@Override
protected EventLoop newChild(Executor executor, Object... args)   throws Exception {
   return new NioEventLoop(this, executor, (SelectorProvider) args[0],((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2]);
}
@Override
public EventExecutor next() {
    return chooser.next();
}

chooser是EventLoop选择策略,默认策略是轮询下一个Loop

private final EventExecutorChooserFactory.EventExecutorChooser chooser;
/**********************/
public final class DefaultEventExecutorChooserFactory implements EventExecutorChooserFactory {

    public static final DefaultEventExecutorChooserFactory INSTANCE = new DefaultEventExecutorChooserFactory();

    private DefaultEventExecutorChooserFactory() { }

    public EventExecutorChooser newChooser(EventExecutor[] executors) {
        //如果是2的指数次mi幂
        if (isPowerOfTwo(executors.length)) {
            return new PowerOfTowEventExecutorChooser(executors);
        } else {
            return new GenericEventExecutorChooser(executors);
        }
    }

    private static boolean isPowerOfTwo(int val) {
        return (val & -val) == val;
    }

    private static final class PowerOfTowEventExecutorChooser implements EventExecutorChooser {
        private final AtomicInteger idx = new AtomicInteger();
        private final EventExecutor[] executors;

        PowerOfTowEventExecutorChooser(EventExecutor[] executors) {
            this.executors = executors;
        }

        //同样获取下个一Loop的下标,通过位与计算更快
        @Override
        public EventExecutor next() {
            return executors[idx.getAndIncrement() & executors.length - 1];
        }
    }

    private static final class GenericEventExecutorChooser implements EventExecutorChooser {
        private final AtomicInteger idx = new AtomicInteger();
        private final EventExecutor[] executors;

        GenericEventExecutorChooser(EventExecutor[] executors) {
            this.executors = executors;
        }

      //获取下一个Loop的下标
        @Override
        public EventExecutor next() {
            return executors[Math.abs(idx.getAndIncrement() % executors.length)];
        }
    }
}
@Override
public ChannelFuture register(Channel channel) {
  return next().register(channel);
}

这里只获取一个EventLoop做注册事件,因为Channel是在所有Loop中共享的

上一篇下一篇

猜你喜欢

热点阅读