下面的例子,你引用和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();
}
所以,現在的解釋(我試試):
- 的
bind()
命令創建監聽對應的插座。它立即返回(不阻塞),所以父通道可能還不可用。
- 第一個
sync()
命令(bind().sync()
)等待綁定完成(如果發生異常,則直接進入finally部分)。在這個階段,渠道已經準備就緒,並聆聽新的聯繫。
channel()
命令獲取此監聽通道(父連接,但尚未連接)。所有客戶都將生成此父母的「孩子」頻道。
- 在您處理程序中,在某些事件發生後,您決定關閉父通道(不是孩子,而是監聽並等待新套接字的人)。要完成此操作,請撥打
parentChannel.close()
(或通過子頻道child.parent().close()
)。
closeFuture()
命令在這個關閉事件中獲得未來。
- 當這個未來結束(完成)時,這是最後的
sync()
命令(closeFuture().sync()
)將發生。
- 父通道關閉後,您可以要求正常關閉綁定通道。
所以這樣做(等待closeFuture然後shutdownGracefully)是關閉連接到此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等待。
這是已知宇宙歷史上最令人敬畏的答案。謝謝! – Marc 2014-11-24 20:18:59