netty执行耗时任务时要放在【eventLoop().execute(runnable)】里面。
示例代码:
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
CharSequence charSequence1 = msg.readCharSequence(msg.readableBytes(), StandardCharsets.UTF_8);
log.info("MyServerChannelInBoundHandler1.channelRead0[" + ctx.channel().remoteAddress() + "]:" + charSequence1);
ByteBuf wbuf = Unpooled.copiedBuffer(charSequence1, StandardCharsets.UTF_8);
AtomicLong tid1 = new AtomicLong(Thread.currentThread().getId());
AtomicLong tid2 = new AtomicLong();
// 注意这里
ctx.channel().eventLoop().execute(new Runnable() {
@Override
public void run() {
try {
tid2.set(Thread.currentThread().getId());
if( Objects.equals(tid1.get(), tid2.get()) ){
log.info("equals(tid1, tid2)"); // 经测试,基本进入的都是这个分支
} else {
log.info("not equals(tid1, tid2)");
}
log.info("channelRead0, runnable 1: start, tid2={}", tid2.get());
Thread.sleep(1000L);
ctx.writeAndFlush(wbuf);
log.info("channelRead0, runnable 1: end, tid2={}", tid2.get());
} catch (InterruptedException e) {
}
}
});
}
本质上来讲【eventLoop().execute(runnable)】仍然是在【workerEventLoopGroup】里面执行,但是netty会先将所有的网络缓冲里面的数据取完,然后触发很多的【channelRead0()】执行很多的【eventLoop().execute(runnable)】,这样【workerEventLoopGroup】里面的线程就可以执行比较满的任务了。
但是如果是在【channelRead0()】里面执行耗时任务,因为耗时任务阻塞了执行线程,【workerEventLoopGroup】里面就不会有很多的任务被同时执行,整个系统的性能就比较差了。