W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
我們會(huì)碰到引導(dǎo)客戶(hù)端 Channel 從另一個(gè) Channel的情況。如果您正在編寫(xiě)一個(gè)代理或者要從其他系統(tǒng)需要檢索數(shù)據(jù)的時(shí)候,這可能發(fā)生。后一種情況是常見(jiàn)的,因?yàn)樵S多 Netty 的應(yīng)用程序集成現(xiàn)有系統(tǒng),例如 web 服務(wù)或數(shù)據(jù)庫(kù)。
你當(dāng)然可以創(chuàng)建一個(gè)新的 Bootstrap 并使用它如9.2.1節(jié)所述,這個(gè)解決方案不一定有效。至少,你需要?jiǎng)?chuàng)建另一個(gè) EventLoop 給新客戶(hù)端 Channel 的,并且 Channel 將會(huì)需要在不同的 Thread 間進(jìn)行上下文切換。
幸運(yùn)的是,由于 EventLoop 繼承自 EventLoopGroup ,您可以通過(guò)傳遞 接收到的 Channel 的 EventLoop 到 Bootstrap 的 group() 方法。這允許客戶(hù)端 Channel 來(lái)操作 相同的 EventLoop,這樣就能消除了額外的線程創(chuàng)建和所有相關(guān)的上下文切換的開(kāi)銷(xiāo)。
為什么共享 EventLoop 呢?
當(dāng)你分享一個(gè) EventLoop ,你保證所有 Channel 分配給 EventLoop 將使用相同的線程,消除上下文切換和相關(guān)的開(kāi)銷(xiāo)。(請(qǐng)記住,一個(gè)EventLoop分配給一個(gè)線程執(zhí)行操作。)
共享一個(gè) EventLoop 描述如下:
Figure 9.4 EventLoop shared between channels with ServerBootstrap and Bootstrap
實(shí)現(xiàn) EventLoop 共享,包括設(shè)置 EventLoop 引導(dǎo)通過(guò)Bootstrap.eventLoop() 方法。這是清單9.5所示。
ServerBootstrap bootstrap = new ServerBootstrap(); //1
bootstrap.group(new NioEventLoopGroup(), //2
new NioEventLoopGroup()).channel(NioServerSocketChannel.class) //3
.childHandler( //4
new SimpleChannelInboundHandler<ByteBuf>() {
ChannelFuture connectFuture;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
Bootstrap bootstrap = new Bootstrap();//5
bootstrap.channel(NioSocketChannel.class) //6
.handler(new SimpleChannelInboundHandler<ByteBuf>() { //7
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
System.out.println("Reveived data");
}
});
bootstrap.group(ctx.channel().eventLoop()); //8
connectFuture = bootstrap.connect(new InetSocketAddress("www.manning.com", 80)); //9
}
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
if (connectFuture.isDone()) {
// do something with the data //10
}
}
});
ChannelFuture future = bootstrap.bind(new InetSocketAddress(8080)); //11
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture) throws Exception {
if (channelFuture.isSuccess()) {
System.out.println("Server bound");
} else {
System.err.println("Bound attempt failed");
channelFuture.cause().printStackTrace();
}
}
});
注意,新的 EventLoop 會(huì)創(chuàng)建一個(gè)新的 Thread。出于該原因,EventLoop 實(shí)例應(yīng)該盡量重用。或者限制實(shí)例的數(shù)量來(lái)避免耗盡系統(tǒng)資源。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: