EventLoop介绍
2024-09-01 10:55:18
在Netty中使用EventLoop接口代表事件循环,EventLoop是从EventExecutor和ScheduledExecutorService扩展而来,所以可以讲任务直接交给EventLoop执行
可以进行各种骚操作
每个通道需要注册到一个EventLoop来处理IO或事件,这是在引导过程中自动完成
//nio
java.nio.channels.SocketChannel mySocket = java.nio.channels.SocketChannel.open();
//netty
SocketChannel ch = new NioSocketChannel(mySocket);
EventLoopGroup group = new NioEventLoopGroup();
//register channel
ChannelFuture registerFuture = group.register(ch);
//de-register channel
ChannelFuture deregisterFuture = ch.deregister();
EventLoop.register(...)和Channel.deregister(...)都是非阻塞异步的,也就是说它们可能不会理解执行完成,可能稍后完成。它们返回ChannelFuture,我们在需要进一步操作或确认完成操作时可以添加一个ChannelFutureLister或在ChannelFuture上同步等待至完成;选择哪一种方式看实际需求,一般建议使用ChannelFutureLister,应避免阻塞。
挂起IO处理
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class)
.handler(new SimpleChannelInboundHandler<ByteBuf>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx,
ByteBuf msg) throws Exception {
//remove this ChannelHandler and de-register
ctx.pipeline().remove(this);
ctx.deregister();
}
});
ChannelFuture future = bootstrap.connect(
new InetSocketAddress("www.baidu.com", 80)).sync();
//....
Channel channel = future.channel();
//re-register channel and add ChannelFutureLister
group.register(channel).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if(future.isSuccess()){
System.out.println("Channel registered");
}else{
System.out.println("register channel on EventLoop fail");
future.cause().printStackTrace();
}
}
});
迁移通道到另一个事件循环
另一个取消注册和注册一个Channel的用例是将一个活跃的Channel移到另一个EventLoop,有下面一些原因可能导致需要这么做:
- 当前EventLoop太忙碌,需要将Channel移到一个不是很忙碌的EventLoop;
- 终止EventLoop释放资源同时保持活跃Channel可以继续使用;
- 迁移Channel到一个执行级别较低的非关键业务的EventLoop中。
EventLoopGroup group = new NioEventLoopGroup();
final EventLoopGroup group2 = new NioEventLoopGroup();
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class)
.handler(new SimpleChannelInboundHandler<ByteBuf>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx,
ByteBuf msg) throws Exception {
// remove this channel handler and de-register
ctx.pipeline().remove(this);
ChannelFuture f = ctx.deregister();
// add ChannelFutureListener
f.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future)
throws Exception {
// migrate this handler register to group2
group2.register(future.channel());
}
});
}
});
ChannelFuture future = b.connect("www.baidu.com", 80);
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future)
throws Exception {
if (future.isSuccess()) {
System.out.println("connection established");
} else {
System.out.println("connection attempt failed");
future.cause().printStackTrace();
}
}
});
最新文章
- Excel函数汇总:
- mysql命令行创建存储过程命令行定时执行sql语句
- Callable、Future和FutureTask
- hdu 5738 2016 Multi-University Training Contest 2 Eureka 计数问题(组合数学+STL)
- kafka.utils.Utils阅读
- USB otg 学习笔记
- Dynamics CRM 开发模板使用手册(插件开发)
- 匿名函数中undefined形参疑问(转载)
- 无序线性搜索(Unordered Linear Search)
- CSS浮动、绝对、相对定位
- eclipse升级Android SDK Tool版本到25.2.5后运行项目报错Unable to build: the file dx.jar was not loaded from the SDK folder
- Visual Studio 2017 - Windows应用程序打包成exe文件(1)- 工具简单总结
- orleans发送广播消息
- Confluence 6 导入一个文本文件
- Linux中安装mongodb
- HDU 2874 Connections between cities(LCA Tarjan)
- 非常干货之Python资源大全
- TCP/IP中的四元组、五元组、七元组
- hdu 1576 A/B 【扩展欧几里德】
- Java擦除