真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Netty中線程名稱的示例分析

小編給大家分享一下Netty中線程名稱的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

成都創(chuàng)新互聯(lián)公司是一家專業(yè)提供烈山企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站制作、成都做網(wǎng)站、H5場景定制、小程序制作等業(yè)務(wù)。10年已為烈山眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)絡(luò)公司優(yōu)惠進(jìn)行中。

NioEventLoop創(chuàng)建過程.
創(chuàng)建的第一個步驟就是創(chuàng)建線程執(zhí)行器ThreadPerTaskExecutor, 這個線程執(zhí)行器就是用來創(chuàng)建Netty底層的線程的. 在學(xué)習(xí)Java的Thread時候,線程默認(rèn)名稱類似thread-0,thread-1,thread-2...以此類推. 而線程的名稱對于我們排查問題的時候也是起到很大作用的, 因此我們在設(shè)計線程池, 也會根據(jù)一定的規(guī)則給線程池中的線程命名, 這也是一個好的習(xí)慣.
在Netty中自然也會給線程池中的線程命名, 接下來我們就分析下它的命名規(guī)則.

Netty中線程名稱的示例分析

上面的圖中有兩個線程池,一個叫bossGroup,另一個叫workerGroup. 它們都屬于EventLoopGroup類型. 前面我們也提高過, bossGroup負(fù)責(zé)接收客戶端請求, workerGroup猶如其名一樣, 是個'工人',負(fù)責(zé)處理客戶端的IO讀寫操作的.

在這兩個Group內(nèi)部有很多個NioEventLoop

Netty中線程名稱的示例分析

如果我們在創(chuàng)建EventLoopGroup時, 沒有傳線程數(shù)量, 那么每個線程池默認(rèn)創(chuàng)建  2*CPU個線程.
每個線程的命名規(guī)則:  nioEventLoop-n-n, 例如nioEventLoop-2-1

接下來我們解釋下后面兩個數(shù)字如何確定的.

我們就拿nioEventLoop-2-1這個為例

備注: 包括dubbo, RocketMQ這樣的框架在內(nèi), 它們底層在使用Netty時的代碼類似, 如下

EventLoopGroup bossGroup = new NioEventLoopGroup(1);EventLoopGroup workerGroup = new NioEventLoopGroup();
上面的代碼主線程main從上往下執(zhí)行的時候, 第一個bossGroup是第1個線程池, 第二個workerGroup是第2個線程池. 依次類推, 如果代碼里new了5個NioEventLoopGroup, 那么第五個group就是第5個線程池.
因此我們示例中的nioEventLoop-2-1的數(shù)字2就表示第2個線程池的意思. 也就是nioEventLoop-2-1這個名字的線程是在第2個線程池中的.

Netty中線程名稱的示例分析

我們繼續(xù)分析nioEventLoop-2-1中數(shù)字1的由來.

每個EventLoopGroup中有多個NioEventLoop. 當(dāng)NioEventLoop在啟動的時候會創(chuàng)建底層的線程.根據(jù)  選擇器EventExecutorChooser, 從線程池中第一個被選擇出來為客戶端提供服務(wù)的NioEventLoop就是第1個線程, 從線程池中第二個被選擇出來為客戶端提供服務(wù)的NioEventLoop就是第2個線程, 以此類推.  所以示例nioEventLoop-2-1中的數(shù)字1就是表示線程池中的第1個線程, 整體就表示第2個線程池中的第1個線程.

Netty中線程名稱的示例分析

備注: 示例nioEventLoop-2-1中的nioEventLoop這個名字是固定的.


實戰(zhàn)

接下來我們從實際去看下它們的名字

服務(wù)端代碼如下


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() {                        @Override                        protected void initChannel(NioSocketChannel ch) {
                           ChannelPipeline channelPipeline = ch.pipeline();                                                        // ...                        }                    });
           // 綁定端口 同步等待成功            ChannelFuture channelFuture1 = serverBootstrap.bind("127.0.0.1", 8080).sync();
           // 等待服務(wù)端監(jiān)聽端口關(guān)閉            channelFuture1.channel().closeFuture().sync();        } finally {            // 執(zhí)行到此處說明服務(wù)端已經(jīng)關(guān)閉            bossGroup.shutdownGracefully();            workerGroup.shutdownGracefully();                }
   }
}

我們把上面的代碼啟動, 然后通過telnet 127.0.0.1 8080方式連接服務(wù)器. 我們使用JDK自帶的jvisualvm查看線程.

Netty中線程名稱的示例分析

通過telnet連接

Netty中線程名稱的示例分析

Netty中線程名稱的示例分析

我們發(fā)現(xiàn)多了兩個線程, 因為我們通過telnet連接了兩次, 所以多了兩個線程. 其中第二個數(shù)字一個是-1, 另一個是-2,表示第1個和第2個線程的意思.

但是

根據(jù)上面的服務(wù)端代碼和前面的講解, 我們明明創(chuàng)建了兩個線程池, 那么第一個數(shù)字應(yīng)該是-1和-2才對, 可是我們實際觀察發(fā)現(xiàn), 卻是-2和-3. (更準(zhǔn)確的說, nioEventLoopGroup-2表示bossGroup, nioEventLoopGroup-3表示workerGroup). 我們的代碼明明只是new出來2個NioEventLoopGroup, 現(xiàn)在實際觀察卻發(fā)現(xiàn)nioEventLoopGroup-1被別人占了.

我們從源碼中尋找答案

當(dāng)我們在代碼中通過new實例化NioEventLoopGroup時, 由于NioEventLoopGroup繼承MultithreadEventExecutorGroup, 所以這個MultithreadEventExecutorGroup也會被實例化.

Netty中線程名稱的示例分析

從圖中我們發(fā)現(xiàn), 會實例化一個DefaultPromise, 其中有個GlobalEventExecutor.INSTANCE. 使用單例模式創(chuàng)建GlobalEventExecutor. 其中GlobalEventExecutor有個屬性

final ThreadFactory threadFactory = new DefaultThreadFactory(DefaultThreadFactory.toPoolName(getClass()), false, Thread.NORM_PRIORITY, null);

再跟蹤下DefaultThreadFactory

Netty中線程名稱的示例分析

我們看右下角發(fā)現(xiàn)了真相, -1被globalEventExecutor-1-使用了.

備注: DefaultThreadFactory這個工廠類在創(chuàng)建bossGroup和workerGroup都會被使用.

以上是“Netty中線程名稱的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


文章名稱:Netty中線程名稱的示例分析
瀏覽地址:http://weahome.cn/article/jjcpgh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部