Netty线程模型、Future、Channel总结和源码分析
创作时间:
作者:
@小白创作中心
Netty线程模型、Future、Channel总结和源码分析
引用
1
来源
1.
http://www.cdweb.net/article/jpoppo.html
Netty线程模型
Netty提供了灵活的线程模型配置,包括单线程Reactor、多线程Reactor和多层线程Reactor。无论采用哪种线程模型,都通过单一的Acceptor接收客户端请求,然后可以创建多个NioEventLoop来处理IO操作。
EventLoop和EventLoopGroup实际上继承了Java的ScheduledExecutorService,具备线程池的特性,线程数量可以根据需要动态配置。例如,配置单线程模型时,只需将线程数量设置为1即可。
Future和Promise机制
Future
Future代表一个异步操作的结果。其主要方法包括:
close()
:关闭Future,但结果未知get()
:获取操作结果,但会阻塞当前线程isDone()
:判断操作是否完成
ChannelFuture是专门用于获取异步返回结果的Future类型。
ChannelFutureListener
可以通过实现ChannelFutureListener接口来获得回调,无需等待get方法返回。
public interface ChannelFutureListener extends GenericFutureListener {
ChannelFutureListener CLOSE = new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) {
future.channel().close();
}
};
ChannelFutureListener CLOSE_ON_FAILURE = new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) {
if (!future.isSuccess()) {
future.channel().close();
}
}
};
ChannelFutureListener FIRE_EXCEPTION_ON_FAILURE = new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) {
if (!future.isSuccess()) {
future.channel().pipeline().fireExceptionCaught(future.cause());
}
}
};
}
连接超时和channel超时配置
在Bootstrap中可以配置连接超时时间:
Bootstrap bootstrap = new Bootstrap();
bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000);
channelFutrue.awaitUninterruptibly(10, TimeUnit.SECONDS);
需要注意以下两点:
- 谨慎使用await,可能导致死锁。
- ChannelFuture超时后如果调用了业务代码重连,而此时IO未超时,将可能导致多条连接并存,设置IO超时时间建议小于业务代码超时时间。
Promise
Promise是Future的升级版,不仅支持读取结果,还支持在回调过程中进行操作。例如,DefaultPromise类中的awaitUninterruptibly方法可以手动打断回调,使进程等待。
public Promise awaitUninterruptibly() {
if (this.isDone()) {
return this;
} else {
boolean interrupted = false;
synchronized(this) {
while(!this.isDone()) {
this.checkDeadLock();
this.incWaiters();
try {
this.wait();
} catch (InterruptedException var9) {
interrupted = true;
} finally {
this.decWaiters();
}
}
}
if (interrupted) {
Thread.currentThread().interrupt();
}
return this;
}
}
其中,checkDeadLock方法用于避免死锁,incWaiters方法限制了最大等待数量为32767。
Channel和Unsafe
Channel负责对外提供操作IO的接口,而Unsafe是Channel的内部接口类,封装了一些不安全的操作,不允许外部直接调用。实际的IO操作最终都在Unsafe中执行。
以Channel的连接操作为例,跟踪其实现过程:
// Channel调用连接
ChannelFuture connect(SocketAddress var1);
// DefaultChannelPipeline中执行,实际是调用尾部的pipeline
public ChannelFuture connect(SocketAddress remoteAddress) {
return this.tail.connect(remoteAddress);
}
// AbstractChannelHandlerContext持续寻找所有handler执行对象
public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
AbstractChannelHandlerContext next = this.findContextOutbound();
next.invoker().invokeConnect(next, remoteAddress, localAddress, promise);
return promise;
}
private AbstractChannelHandlerContext findContextOutbound() {
AbstractChannelHandlerContext ctx = this;
do {
ctx = ctx.prev;
} while(!ctx.outbound);
return ctx;
}
// 实际执行是寻找到Unsafe的Invoker
public ChannelHandlerInvoker invoker() {
return this.invoker == null ? this.channel().unsafe().invoker() : this.invoker;
}
public void invokeConnect(final ChannelHandlerContext ctx, final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) {
if (remoteAddress == null) {
throw new NullPointerException("remoteAddress");
} else if (ChannelHandlerInvokerUtil.validatePromise(ctx, promise, false)) {
if (this.executor.inEventLoop()) {
ChannelHandlerInvokerUtil.invokeConnectNow(ctx, remoteAddress, localAddress, promise);
} else {
this.safeExecuteOutbound(new OneTimeTask() {
public void run() {
ChannelHandlerInvokerUtil.invokeConnectNow(ctx, remoteAddress, localAddress, promise);
}
}, promise);
}
}
}
热门推荐
【民法典】遭遇家暴如何保护自己?
全国万亿GDP城市成绩单出炉,谁在领跑?下一个会是谁?
惠州威海等地海景房大跌价:有的145平25万成交,大量二手房待售
从"车看灯"到"灯看车"!贵阳实现交通信号智能控制破解拥堵难题
2025“电白沉香年例”成功举行,探讨沉香药用价值与产业发展
沉香的功效与作用
西安到深圳自驾游:打卡黄鹤楼、庐山、黄山
第一次买房的注意事项及流程解析
古诗中的“临渊”意境,你读懂了吗?
《临渊行》:玄幻世界的教育变革之路
《临渊》:从虐恋情深到温暖希望的人生启示
得力橡皮筋:一根橡皮筋的科技之旅
一根橡皮筋的N种玩法:从家庭整理到创意DIY
打卡沈阳和平区:东北解放碑&老北市必玩攻略
盗汗的10个食疗方法
一动就出汗,止汗神药牡蛎散
胃病都是怎么引起的,生活中我们应当如何预防
如何通过调整饮食来改善肠胃健康
新电脑如何调整显卡驱动程序?详细步骤与优化指南
“深圳后花园”跌下神坛,小城惠州何去何从?
《新生》取景地探秘:厦门的这些经典打卡点,你都去过吗?
上海172路公交线路全攻略:站点时刻表及实用建议
贵阳十大人文旅游景点:探寻文化魅力,感受历史沉淀
台积电产能告急:汽车电子芯片荒何时了?
金价狂飙,未来能否突破5000美元大关?
纯电 vs 插混:谁才是家庭用车的最优解?
猫咪发烧了怎么办
宠物小猫肛温测量技巧详解(如何正确地为小猫测量肛温)
黄家驹:香港摇滚传奇永不灭
Beyond主唱黄家驹:从摇滚巨星到银幕追梦人