Netty中线程名称的示例分析
Netty中线程名称的示例分析
小编给大家分享一下Netty中线程名称的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
在这两个Group内部有很多个NioEventLoop
接下来我们解释下后面两个数字如何确定的.
我们就拿nioEventLoop-2-1这个为例
备注: 包括dubbo, RocketMQ这样的框架在内, 它们底层在使用Netty时的代码类似, 如下
EventLoopGroupbossGroup=newNioEventLoopGroup(1);EventLoopGroupworkerGroup=newNioEventLoopGroup();
我们继续分析nioEventLoop-2-1中数字1的由来.
备注: 示例nioEventLoop-2-1中的nioEventLoop这个名字是固定的.
实战
接下来我们从实际去看下它们的名字
服务端代码如下
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.FixedLengthFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;
import java.util.concurrent.TimeUnit;
public class Server {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap serverBootstrap = new ServerBootstrap();
try{
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel ch) {
ChannelPipeline channelPipeline = ch.pipeline();
// ...
}
});
// 绑定端口 同步等待成功
ChannelFuture channelFuture1 = serverBootstrap.bind("127.0.0.1", 8080).sync();
// 等待服务端监听端口关闭
channelFuture1.channel().closeFuture().sync();
} finally {
// 执行到此处说明服务端已经关闭
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
我们把上面的代码启动, 然后通过telnet 127.0.0.1 8080方式连接服务器. 我们使用JDK自带的jvisualvm查看线程.
通过telnet连接
我们发现多了两个线程, 因为我们通过telnet连接了两次, 所以多了两个线程. 其中第二个数字一个是-1, 另一个是-2,表示第1个和第2个线程的意思.
但是
根据上面的服务端代码和前面的讲解, 我们明明创建了两个线程池, 那么第一个数字应该是-1和-2才对, 可是我们实际观察发现, 却是-2和-3. (更准确的说, nioEventLoopGroup-2表示bossGroup, nioEventLoopGroup-3表示workerGroup). 我们的代码明明只是new出来2个NioEventLoopGroup, 现在实际观察却发现nioEventLoopGroup-1被别人占了.
我们从源码中寻找答案
当我们在代码中通过new实例化NioEventLoopGroup时, 由于NioEventLoopGroup继承MultithreadEventExecutorGroup, 所以这个MultithreadEventExecutorGroup也会被实例化.
从图中我们发现, 会实例化一个DefaultPromise, 其中有个GlobalEventExecutor.INSTANCE. 使用单例模式创建GlobalEventExecutor. 其中GlobalEventExecutor有个属性
finalThreadFactorythreadFactory=newDefaultThreadFactory(DefaultThreadFactory.toPoolName(getClass()),false,Thread.NORM_PRIORITY,null);
再跟踪下DefaultThreadFactory
我们看右下角发现了真相, -1被globalEventExecutor-1-使用了.
备注: DefaultThreadFactory这个工厂类在创建bossGroup和workerGroup都会被使用.
以上是“Netty中线程名称的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注恰卡编程网行业资讯频道!