欢迎微信搜索并关注“小猴子的技术笔记”公众号 私信我 领取丰富的视频学习资料!
在最初开始学习netty的过程中经常使用的是主函数启动netty服务端的代码,会加入"future.channel().closeFuture().sync();"这样一句话,这在我刚开始学习netty的时候还是比较费解的。
接下来将有两个例子进行对比来感受一下添加上面那句话给程序带来的影响。我先写了一个添加了"future.channel().closeFuture().sync();"的代码示例:
public class NettyServer {
public static void main(String[] args) {
EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup worker = new NioEventLoopGroup();
try {
ServerBootstrap server = new ServerBootstrap();
server.group(boss, worker).channel(NioServerSocketChannel.class).childHandler(new NettyServerInitializer());
ChannelFuture future = server.bind(9999).sync();
future.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
}
然后我们通过连接工具测试进行测试,发现可以连接上去,也就是说明这个服务是可以的。
然后注意观察IDEA的进程标识,你会发现这里一直是在后台运行的。请注意这里是一直运行的,后面将会有对比,这里注意下。
也许目前还是不太明白"future.channel().closeFuture().sync();"这句话到底是干什么的,别急继续往下看。
future.channel().closeFuture().sync();
如果你仔细观察的话,会发现我们的代码使用了try-catch-finally,如果把这段代码注释掉在测试下:
public class NettyServer {
public static void main(String[] args) {
EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup worker = new NioEventLoopGroup();
try {
ServerBootstrap server = new ServerBootstrap();
server.group(boss, worker).channel(NioServerSocketChannel.class).childHandler(new NettyServerInitializer());
ChannelFuture channelFuture = server.bind(9999).sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
}
运行程序之后,你会发现,程序自动结束了过了一会儿,下图标变黑了,也就是说程序自上而下执行完了,调用了finally里面的代码,优雅的关闭了netty。如果服务端执行完毕就关闭的话,那么客户端将无法在连接上来。
也许到这里你会有点明白了,这个说白了也就是阻塞main函数继续往下执行,防止finally的语句块被触发。我在之前的文章讲过,一个线程的启动必须由一个主线程进行调度,线程它不会平白无故的产生,这里调起netty服务的线程就是main函数。而main函数使用了finally,不管程序发生什么只要运行结束了,finally中的语句一定会执行,也就关闭了netty服务。
其实通过官网的注释也能够看到,标注的是等待服务端socket结束,在这个例子中将不会被执行。
既然这样,那么我不调用最后关闭线程的代码是不是就可以了呢?接下来写个例子测试一下:
public class NettyServer {
public static void main(String[] args) {
EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup worker = new NioEventLoopGroup();
ServerBootstrap server = new ServerBootstrap();
server.group(boss, worker).channel(NioServerSocketChannel.class).childHandler(new NettyServerInitializer());
try {
server.bind(9999).sync();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行等一会儿,观察IDEA的后台进程发现也是一直在运行的,然后使用工具连接进行测试一下也是可以连接上去的。
总的来说如果使用了finally进行关闭netty服务的话,"future.channel().closeFuture().sync();“防止代码运行完服务就被关闭了,并且这里会一直阻塞着,防止进程结束。没有使用finally的话可以去掉"future.channel().closeFuture().sync();”。不过为了出现异常就释放掉netty的资源还是建议加上finally。
欢迎微信搜索并关注“小猴子的技术笔记”公众号 私信我 领取丰富的视频学习资料!