本文基于windows下的netty4.1.41.Final版本,以后也都是基于此版本, 注意,不太相关的代码笔者会直接省略
本文主要分析以下两行代码
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
//事件循环组的作用是注册channel,应该是把channel注册到selector上?
public interface EventLoopGroup extends EventExecutorGroup {
//一个事件循环组有多个事件循环EventLoop,用数组存储,然后以取模的方式循环next下一个元素,后面源码应该会具体说明
@Override
EventLoop next();
//注册channnel,返回future,可以查看注册结果
ChannelFuture register(Channel channel);
//注册channnel,返回future,可以查看注册结果(ChannelPromise 有channel的引用)
ChannelFuture register(ChannelPromise promise);
}
EventLoop 事件循环接口如下
//一旦channnel被注册了,EventLoop会处理channel所有的IO操作
public interface EventLoop extends OrderedEventExecutor, EventLoopGroup {
//返回当前EventLoop事件循环属于哪一个事件循环组
@Override
EventLoopGroup parent();
}
//NioEventLoopGroup#NioEventLoopGroup(nThreads)
public NioEventLoopGroup(int nThreads) {
//bossGroup传了1,nThreads=1,workerGroup没有传参数,nThreads=0
//Executor为null
this(nThreads, (Executor) null);
}
--------------------------------------------------->>>>>
public NioEventLoopGroup(int nThreads, Executor executor) {
//我们传的线程数,执行器null
//nio编程要获得一个selector时需要Selector.open()
//而Selector.open()里则是SelectorProvider.provider().openSelector()
//这里只是获得一个SelectorProvider而没有进一步获得selector是因为后续netty要对selector做优化
this(nThreads, executor, SelectorProvider.provider());
}
--------------------------------------------------->>>>>
public NioEventLoopGroup(int nThreads, Executor executor, final SelectorProvider selectorProvider) {
//线程个数,null,selectorProvider,默认选择策略工厂(见源码分析之默认选择策略工厂)
this(nThreads, executor, selectorProvider, DefaultSelectStrategyFactory.INSTANCE);
}
--------------------------------------------------->>>>>
public NioEventLoopGroup(int nThreads, Executor executor, final SelectorProvider selectorProvider,
final SelectStrategyFactory selectStrategyFactory) {
//又加了一个拒绝策略的处理器,应该是任务队列满了执行响应的逻辑吧
super(nThreads, executor, selectorProvider, selectStrategyFactory, RejectedExecutionHandlers.reject());
}
--------------------------------------------------->>>>>
protected MultithreadEventLoopGroup(int nThreads, Executor executor, Object... args) {
//不设置线程个数默认为cpu核心数*2
//args:selectorProvider,selectStrategyFactory,rejectHandler
super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, args);
}
--------------------------------------------------->>>>>
protected MultithreadEventExecutorGroup(int nThreads, Executor executor, Object... args) {
//DefaultEventExecutorChooserFactory.INSTANCE(见源码分析之事件执行器选择工厂)
//args:selectorProvider,selectStrategyFactory,rejectHandler
this(nThreads, executor, DefaultEventExecutorChooserFactory.INSTANCE, args);
}
--------------------------------------------------->>>>>
protected MultithreadEventExecutorGroup(int nThreads, Executor executor,
EventExecutorChooserFactory chooserFactory, Object... args) {
if (executor == null) {
//单任务线程池
executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
}
//children: EventExecutor[];
children = new EventExecutor[nThreads];
for (int i = 0; i < nThreads; i ++) {
//重要,见源码分析newChild
children[i] = newChild(executor, args);
}
//根据nThreads是不是2的幂次方来决定选择器,是的话用&,或者取模%
chooser = chooserFactory.newChooser(children);
}
//默认选择策略工厂
public final class DefaultSelectStrategyFactory implements SelectStrategyFactory {
public static final SelectStrategyFactory INSTANCE = new DefaultSelectStrategyFactory();
private DefaultSelectStrategyFactory() { }
//DefaultSelectStrategyFactory.INSTANCE.newSelectStrategy()
@Override
public SelectStrategy newSelectStrategy() {
return DefaultSelectStrategy.INSTANCE;
}
}
//默认的选择策略
final class DefaultSelectStrategy implements SelectStrategy {
static final SelectStrategy INSTANCE = new DefaultSelectStrategy();
private DefaultSelectStrategy() { }
//有任务selectNow,否则select,这里我暂时不是很懂,下次懂了补上解释? todo
@Override
public int calculateStrategy(IntSupplier selectSupplier, boolean hasTasks) throws Exception {
return hasTasks ? selectSupplier.get() : SelectStrategy.SELECT;
}
}
public final class DefaultEventExecutorChooserFactory implements EventExecutorChooserFactory {
public static final DefaultEventExecutorChooserFactory INSTANCE = new DefaultEventExecutorChooserFactory();
private DefaultEventExecutorChooserFactory() { }
@SuppressWarnings("unchecked")
@Override
public EventExecutorChooser newChooser(EventExecutor[] executors) {
//如果线程数是2的幂次方,真的是一点点性能优化都不放过啊
if (isPowerOfTwo(executors.length)) {
//采用效率高的&
return new PowerOfTwoEventExecutorChooser(executors);
} else {
//否则采用效率低的%
return new GenericEventExecutorChooser(executors);
}
}
private static boolean isPowerOfTwo(int val) {
return (val & -val) == val;
//return val&(val-1)==0;
}
private static final class PowerOfTwoEventExecutorChooser implements EventExecutorChooser {
private final AtomicInteger idx = new AtomicInteger();
private final EventExecutor[] executors;
PowerOfTwoEventExecutorChooser(EventExecutor[] executors) {
this.executors = executors;
}
@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;
}
@Override
public EventExecutor next() {
return executors[Math.abs(idx.getAndIncrement() % executors.length)];
}
}
}
NioEventLoopGroup#newChild
@Override
protected EventLoop newChild(Executor executor, Object... args) throws Exception {
//args:selectorProvider,selectStrategyFactory,rejectHandler
EventLoopTaskQueueFactory queueFactory = args.length == 4 ? (EventLoopTaskQueueFactory) args[3] : null;
return new NioEventLoop(this, executor, (SelectorProvider) args[0],
((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2], queueFactory);
}
--------------------------------------------------->>>>>
NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider,
SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler,
EventLoopTaskQueueFactory queueFactory) {
//queueFactory=null
super(parent, executor, false, newTaskQueue(queueFactory), newTaskQueue(queueFactory),
rejectedExecutionHandler);
provider = selectorProvider;
//极其重要,netty对selector做的优化
final SelectorTuple selectorTuple = openSelector();
//netty包装过的selector
selector = selectorTuple.selector;
//未包装的selector,nio原生的selector
unwrappedSelector = selectorTuple.unwrappedSelector;
selectStrategy = strategy;
}
--------------------------------------------------->>>>>
调用父类构造
protected SingleThreadEventLoop(EventLoopGroup parent, Executor executor,boolean addTaskWakesUp,
Queue<Runnable> taskQueue, Queue<Runnable> tailTaskQueue,
RejectedExecutionHandler rejectedExecutionHandler) {
super(parent, executor, addTaskWakesUp, taskQueue, rejectedExecutionHandler);
tailTasks = ObjectUtil.checkNotNull(tailTaskQueue, "tailTaskQueue");
}
--------------------------------------------------->>>>>
调用父类构造
protected SingleThreadEventExecutor(EventExecutorGroup parent, Executor executor,
boolean addTaskWakesUp, Queue<Runnable> taskQueue,
RejectedExecutionHandler rejectedHandler) {
super(parent);
this.addTaskWakesUp = addTaskWakesUp;
this.maxPendingTasks = DEFAULT_MAX_PENDING_EXECUTOR_TASKS;
this.executor = ThreadExecutorMap.apply(executor, this);
this.taskQueue = ObjectUtil.checkNotNull(taskQueue, "taskQueue");
rejectedExecutionHandler = ObjectUtil.checkNotNull(rejectedHandler, "rejectedHandler");
}
--------------------------------------------------->>>>>
调用父类构造
protected AbstractScheduledEventExecutor(EventExecutorGroup parent) {
super(parent);
}
--------------------------------------------------->>>>>
调用父类构造
protected AbstractEventExecutor(EventExecutorGroup parent) {
this.parent = parent;
}
private SelectorTuple openSelector() {
//用jdk的provider打开一个未包装的selector
Selector unwrappedSelector = provider.openSelector();
//是否禁用selectedKeySet优化,如果禁用的话直接返回未包装的selector,否则走下面的优化过程
if (DISABLE_KEY_SET_OPTIMIZATION) {
return new SelectorTuple(unwrappedSelector);
}
//反射拿到SelectorImpl class
Object maybeSelectorImplClass = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
try {
return Class.forName(
"sun.nio.ch.SelectorImpl",
false,
PlatformDependent.getSystemClassLoader());
} catch (Throwable cause) {
return cause;
}
}
});
//SelectorImpl.class
final Class<?> selectorImplClass = (Class<?>) maybeSelectorImplClass;
//netty优化过的,用数组实现比Set效率高
final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();
Object maybeException = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
try {
///反射得到SelectorImpl类的selectedKeys,publicSelectedKeys属性
Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");
ReflectionUtil.trySetAccessible(selectedKeysField, true);
ReflectionUtil.trySetAccessible(publicSelectedKeysField, true);
//用netty写的selectedKeySet替换掉jdk的
selectedKeysField.set(unwrappedSelector, selectedKeySet);
publicSelectedKeysField.set(unwrappedSelector, selectedKeySet);
return null;
} catch (NoSuchFieldException e) {
return e;
} catch (IllegalAccessException e) {
return e;
}
}
});
selectedKeys = selectedKeySet;
return new SelectorTuple(unwrappedSelector,
new SelectedSelectionKeySetSelector(unwrappedSelector, selectedKeySet));
}
1:nThreads不设置使用CPU核心数*2
2:获取下一个执行器的策略是根据nThreads个数是否是2的幂次方来决定的,是2的幂次方使用&运算,否则使用%循环使用
3:对于selector,不是直接SelectorProvider.provider().openSelector(), 而是优化过
4:如果没有禁用selectedKey优化,Netty会使用自定的SelectedSelectionKeySet替换SelectorImpl的publicSelectedKeys、selectedKeys
5:貌似NioEventLoopGroup都是在走构造器重载,走完了也才把selector初始化完毕了