以下是您引用的示例并添加您的问题sync()
方法,这里是示例代码:
EventLoopGroup bossGroup = new NioEventLoopGroup(numBossThreads);
EventLoopGroup workerGroup = new NioEventLoopGroup(numWorkerThreads);
ServerBootstrap sb1 = null;
ServerBootstrap sb2 = null;
ServerBootstrap sb3 = null;
Channel ch1 = null;
Channel ch2 = null;
Channel ch3 = null;
try {
sb1 = new ServerBootstrap();
sb1.group(bossGroup, workerGroup);
...
ch1 = sb1.bind().sync().channel();
sb2 = new ServerBootstrap();
sb2.group(bossGroup, workerGroup);
...
ch2 = sb2.bind().sync().channel();
sb3 = new ServerBootstrap();
sb3.group(bossGroup, workerGroup);
...
ch3 = sb3.bind().sync().channel();
} finally {
// Now waiting for the parent channels (the binded ones) to be closed
if (ch1 != null) {
ch1.closeFuture().sync();
}
if (b1 != null) {
b1.shutdownGracefully();
}
if (ch2 != null) {
ch2.closeFuture().sync();
}
if (b2 != null) {
b2.shutdownGracefully();
}
if (ch3 != null) {
ch3.closeFuture().sync();
}
if (b3 != null) {
b3.shutdownGracefully();
}
现在解释一下(我尝试):
- The
bind()
命令创建监听对应的socket。它立即返回(不阻塞),因此父通道可能尚不可用。
- 首先
sync()
命令 (bind().sync()
)等待绑定完成(如果引发异常,则直接进入finally部分)。在此阶段,通道已准备就绪并正在侦听新连接。
- The
channel()
命令获取此监听通道(父通道,尚未连接到任何通道)。所有客户端都将生成该父通道的“子”通道。
- 在您的处理程序中,在发生某些事件后,您决定关闭父通道(不是子通道,而是侦听并等待新套接字的通道)。要完成此操作,只需致电
parentChannel.close()
(或来自子频道child.parent().close()
).
- The
closeFuture()
命令正在获取本次闭幕事件的未来。
- 当这个未来结束(完成)时,这就是最后的时刻
sync()
命令 (closeFuture().sync()
) 会发生。
- 父通道关闭后,您可以请求正常关闭绑定通道。
因此,这样做(等待 closeFuture 然后 shutdownGraceively)是关闭附加到此 ServerBootstrap 的所有资源的干净方法。
当然你可以改变一些事情。例如,当您想在正常关闭之前阻止时,不首先获取通道,而是稍后才获取。
EventLoopGroup bossGroup = new NioEventLoopGroup(numBossThreads);
EventLoopGroup workerGroup = new NioEventLoopGroup(numWorkerThreads);
ServerBootstrap sb1 = null;
ServerBootstrap sb2 = null;
ServerBootstrap sb3 = null;
ChannelFuture cf1 = null;
ChannelFuture cf2 = null;
ChannelFuture cf3 = null;
try {
sb1 = new ServerBootstrap();
sb1.group(bossGroup, workerGroup);
...
cf1 = sb1.bind();
sb2 = new ServerBootstrap();
sb2.group(bossGroup, workerGroup);
...
cf2 = sb2.bind();
sb3 = new ServerBootstrap();
sb3.group(bossGroup, workerGroup);
...
cf3 = sb3.bind();
} finally {
// Now waiting for the parent channels (the binded ones) to be closed
if (cf1 != null) {
cf1.sync().channel().closeFuture().sync();
}
if (cf2 != null) {
c2.sync().channel().closeFuture().sync();
}
if (cf3 != null) {
cf3.sync().channel().closeFuture().sync();
}
if (b1 != null) {
b1.shutdownGracefully();
}
if (b2 != null) {
b2.shutdownGracefully();
}
if (b3 != null) {
b3.shutdownGracefully();
}
这样,您在打开所有 3 个通道时根本不会阻塞,而是等待所有 3 个通道完成后再关闭它们。
最后,如果你不阻止的话bind()
事件然后closeFuture()
事件,由您决定在事件发生后您将如何等待sbx.bind()
命令和之前关闭 ServerBootstraps。