??? 真正实现生成selector的方法是在的NioEventLoopGroup的父类MultithreadEventExecutorGroup中MultithreadEventExecutorGroup(int nThreads, ThreadFactory threadFactory, Object... args)方法
?
参数:1、nThreads为线程数量,也就是nio中selector的数量,默认为CPU核数*2
??? (DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt( "io.netty.eventLoopThreads", Runtime.getRuntime().availableProcessors() * 2)))
?
??? 2、ThreadFactory 线程工厂
?
??? 3、args参数,这里的参数主要的是用于生成java nio的Seletor的对象,这个参数我们没有传进去,Netty会自动判断并使用java.nio.channels.spi.SelectorProvider对象;
?
?
?? MultithreadEventExecutorGroup方法中主要的源码:
?
if (nThreads <= 0) {
throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads));
}
if (threadFactory == null) {
threadFactory = newDefaultThreadFactory();
}
children = new SingleThreadEventExecutor[nThreads];
for (int i = 0; i < nThreads; i ++) {
boolean success = false;
try {
children[i] = newChild(threadFactory, args);
success = true;
} catch (Exception e) {
// TODO: Think about if this is a good exception type
throw new IllegalStateException("failed to create a child event loop", e);
}
?? 这段代码中最主要的是newChild(threadFactory, args)这句话主要是生成了NioEventLoop对象,NioEventLoop对象调用openSelector方法生成了nio的选择器selector
private Selector openSelector() {
final Selector selector;
try {
selector = provider.openSelector();
} catch (IOException e) {
throw new ChannelException("failed to open a new selector", e);
}
if (DISABLE_KEYSET_OPTIMIZATION) {
return selector;
}
try {
SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();
Class<?> selectorImplClass =
Class.forName("sun.nio.ch.SelectorImpl", false, ClassLoader.getSystemClassLoader());
// Ensure the current selector implementation is what we can instrument.
if (!selectorImplClass.isAssignableFrom(selector.getClass())) {
return selector;
}
Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");
selectedKeysField.setAccessible(true);
publicSelectedKeysField.setAccessible(true);
selectedKeysField.set(selector, selectedKeySet);
publicSelectedKeysField.set(selector, selectedKeySet);
selectedKeys = selectedKeySet;
logger.trace("Instrumented an optimized java.util.Set into: {}", selector);
} catch (Throwable t) {
selectedKeys = null;
logger.trace("Failed to instrument an optimized java.util.Set into: {}", selector, t);
}
return selector;
}
?
最后在绑定端口时,由ServerBootstrap的父类AbstractBootstrap的initAndRegiste方法调用NioEventLoopGroup的register方法将serversocketchannel注册到selector中并开始监听.
?
?
1221122 2016/11/9 9:57:22 发表
深入浅出Netty源码剖析 课程观看地址:http://.xuetuwuyou.com/course/157 课程出自学途无忧网:http://.xuetuwuyou.com