参考资料
NioEventLoopGroup源码分析
启动作用
1. 和普通我们写JKD Nio的程序是一样,只是做了组件上的封装
2. 首先是创建NioServerSocketChannel, 注册到对应的NioEventLoop上
,启动一个线程,扫描NioEventLoop的Selector的连接事件
3. 然后将NioServerSocketChannel绑定到对应端口
示例
EventLoopGroup bossEventLoopGroup = new NioEventLoopGroup ( 2 ) ;
EventLoopGroup workEventExecutors = new NioEventLoopGroup ( 2 ) ;
ServerBootstrap serverBootstrap= new ServerBootstrap ( ) ;
try {
serverBootstrap. group ( bossEventLoopGroup, workEventExecutors)
. channel ( NioServerSocketChannel. class )
. localAddress ( port)
. childHandler ( new ChannelInitializer < SocketChannel> ( ) {
@Override
protected void initChannel ( SocketChannel socketChannel) throws Exception {
socketChannel. pipeline ( ) . addLast ( new MyHandler ( ) ) ;
}
} ) ;
ChannelFuture sync = serverBootstrap. bind ( ) . sync ( ) ;
ChannelFuture channelFuture = sync. channel ( ) . closeFuture ( ) ;
channelFuture. sync ( ) ;
System. out. println ( "服务启动成功" ) ;
} catch ( Exception e) {
bossEventLoopGroup. shutdownGracefully ( ) ;
workEventExecutors. shutdownGracefully ( ) ;
}
ServerBootstrap的属性简单介绍
private volatile EventLoopGroup childGroup;
private volatile ChannelHandler childHandler;
volatile EventLoopGroup group;
private volatile ChannelFactory< ? extends C > channelFactory;
private volatile ChannelHandler handler;
bind方法分析
private ChannelFuture doBind ( final SocketAddress localAddress) {
final ChannelFuture regFuture = initAndRegister ( ) ;
final Channel channel = regFuture. channel ( ) ;
. . . . .
doBind0 ( regFuture, channel, localAddress, promise) ;
}
initAndRegister方法
final ChannelFuture initAndRegister ( ) {
Channel channel = null;
try {
channel = channelFactory. newChannel ( ) ;
init ( channel) ;
} catch ( Throwable t) {
}
ChannelFuture regFuture = config ( ) . group ( ) . register ( channel) ;
if ( regFuture. cause ( ) != null) {
if ( channel. isRegistered ( ) ) {
channel. close ( ) ;
} else {
channel. unsafe ( ) . closeForcibly ( ) ;
}
}
return regFuture;
}
newChannel方法
channel = channelFactory. newChannel ( ) ;
public B channel ( Class< ? extends C > channelClass) {
if ( channelClass == null) {
throw new NullPointerException ( "channelClass" ) ;
}
return channelFactory ( new ReflectiveChannelFactory < C> ( channelClass) ) ;
}
@Override
public T newChannel ( ) {
try {
return clazz. getConstructor ( ) . newInstance ( ) ;
} catch ( Throwable t) {
throw new ChannelException ( "Unable to create Channel from class " + clazz, t) ;
}
}
init(channel)方法
void init ( Channel channel) throws Exception {
final Map< ChannelOption< ? > , Object> options = options0 ( ) ;
synchronized ( options) {
setChannelOptions ( channel, options, logger) ;
}
ChannelPipeline p = channel. pipeline ( ) ;
p. addLast ( new ChannelInitializer < Channel> ( ) {
@Override
public void initChannel ( final Channel ch) throws Exception {
final ChannelPipeline pipeline = ch. pipeline ( ) ;
ChannelHandler handler = config. handler ( ) ;
if ( handler != null) {
pipeline. addLast ( handler) ;
}
ch. eventLoop ( ) . execute ( new Runnable ( ) {
@Override
public void run ( ) {
pipeline. addLast ( new ServerBootstrapAcceptor (
ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs) ) ;
}
} ) ;
}
} ) ;
}
register(channel)
ChannelFuture regFuture = config ( ) . group ( ) . register ( channel)
@Override
public ChannelFuture register ( Channel channel) {
return next ( ) . register ( channel) ;
}
@Override
public EventExecutor next ( ) {
return chooser. next ( ) ;
}
@Override
public ChannelFuture register ( Channel channel) {
return register ( new DefaultChannelPromise ( channel, this ) ) ;
}
@Override
public ChannelFuture register ( final ChannelPromise promise) {
ObjectUtil. checkNotNull ( promise, "promise" ) ;
promise. channel ( ) . unsafe ( ) . register ( this , promise) ;
return promise;
}
public final void register ( EventLoop eventLoop, final ChannelPromise promise) {
AbstractChannel. this . eventLoop = eventLoop;
if ( eventLoop. inEventLoop ( ) ) {
register0 ( promise) ;
} else {
eventLoop. execute ( new Runnable ( ) {
@Override
public void run ( ) {
register0 ( promise) ;
}
} ) ;
}
NioEventLoop的execute方法
public void execute ( Runnable task) {
if ( task == null) {
throw new NullPointerException ( "task" ) ;
}
boolean inEventLoop = inEventLoop ( ) ;
if ( inEventLoop) {
addTask ( task) ;
} else {
startThread ( ) ;
addTask ( task) ;
if ( isShutdown ( ) && removeTask ( task) ) {
reject ( ) ;
}
}
}
private void startThread ( ) {
if ( state == ST_NOT_STARTED) {
if ( STATE_UPDATER. compareAndSet ( this , ST_NOT_STARTED, ST_STARTED) ) {
doStartThread ( ) ;
}
}
}
private void doStartThread ( ) {
assert thread == null;
executor. execute ( new Runnable ( ) {
@Override
public void run ( ) {
thread = Thread. currentThread ( ) ;
if ( interrupted) {
thread. interrupt ( ) ;
}
SingleThreadEventExecutor. this . run ( ) ;
}
}
}
@Override
protected void run ( ) {
for ( ; ; ) {
try {
switch ( selectStrategy. calculateStrategy ( selectNowSupplier, hasTasks ( ) ) ) {
case SelectStrategy. CONTINUE:
continue ;
case SelectStrategy. SELECT:
select ( wakenUp. getAndSet ( false ) ) ;
if ( wakenUp. get ( ) ) {
selector. wakeup ( ) ;
}
default :
}
cancelledKeys = 0 ;
needsToSelectAgain = false ;
final int ioRatio = this . ioRatio;
if ( ioRatio == 100 ) {
try {
processSelectedKeys ( ) ;
} finally {
runAllTasks ( ) ;
}
} else {
final long ioStartTime = System. nanoTime ( ) ;
try {
processSelectedKeys ( ) ;
} finally {
final long ioTime = System. nanoTime ( ) - ioStartTime;
runAllTasks ( ioTime * ( 100 - ioRatio) / ioRatio) ;
}
}
} catch ( Throwable t) {
handleLoopException ( t) ;
}
try {
if ( isShuttingDown ( ) ) {
closeAll ( ) ;
if ( confirmShutdown ( ) ) {
return ;
}
}
} catch ( Throwable t) {
handleLoopException ( t) ;
}
}
}
总结
1. 本节主要是探索服务端怎么运行起来的,怎么绑定一个NioEventLoop,然后工作起来的一个流程
2. 下面章节还需要分析轮训里面具体做了一些什么,channel,NioEventLoop,handle,连接处理器接受连接等的细节