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);
}
}
}
热门推荐
新版国家医保药品目录今起实施 快来查查哪些药可以走医保!
怎么将旧硬盘数据迁移到新硬盘
深紫外LED杀毒灭菌技术在家电产品中的应用
《战舰世界》HL系巡洋舰战力详解
MySQL深度分页问题:为什么LIMIT越来越慢?如何优化?
三亚旅游攻略:美食、住宿、景点一站式深度体验分享
大数据与会计专业融合:如何通过数据分析提升财务决策?
自制解暑饮品,轻松驱走炎热
如何高产种植管理芹菜?
从至宝丹到至宝丹体:一剂名贵中药的文化传奇
西安咸阳国际机场三期扩建工程T5航站楼及综合交通中心:长安盛殿 丝路新港
冉闵的《杀胡令》是如何颁发出来的?是为民族大义还是一己私欲?
替诺福韦二代用药期间的饮食注意事项
垂丝茉莉不开花是什么原因造成的
福州大学材料科学学科进入ESI全球前1‰,跻身世界一流学科行列
盖姓的来源
年轻人都想“上岸”,真正的“岸”是什么?
全面指南:从醴陵前往庐山旅游的详细路线与建议
1997年亚洲金融风暴 : 6个原因, 9个影响, 8个对策
如何理解复利终值系数的计算方法?这些计算方法如何影响财务规划?
流动负债管理的关键与挑战:优化资金流动,实现稳健发展
汽车空调系统故障检查方法及冷却液问题处理
市值管理火了!40多家A股公司披露相关制度,哪些资本运作值得划重点
土豆皮可以吃吗?营养师告诉你真相
高产蛋鸡哪个品种最好
神经节苷脂的作用是什么
网上MBTI测试准确吗?专家解析其可靠性问题
如何报考注册会计师证:详细指南与步骤
太赫兹超材料及其成像应用研究进展
环氧树脂AB胶的介绍以及用途和成分