[编织消息框架][netty源码分析]5 EventLoopGroup 实现类NioEventLoopGroup职责与实现
分析NioEventLoopGroup最主有两个疑问
1.next work如何分配NioEventLoop
2.boss group 与child group 是如何协作运行的
从EventLoopGroup接口约定通过register方法从channel或promise转换成ChannelFuture对象
next方法就是用来分配NioEventLoop
public interface EventLoopGroup extends EventExecutorGroup {
@Override
EventLoop next();
ChannelFuture register(Channel channel);
ChannelFuture register(ChannelPromise promise);
@Deprecated
ChannelFuture register(Channel channel, ChannelPromise promise);
}
为了节省篇副,做了代码整理
1.NioEventLoopGroup构造时绑定SelectorProvider.provider(),通过newChild生成单个EventLoop
2.next实现是个环形循环
3.register方法是将channel转换成ChannelFuture
读者如果感兴趣可以在这几个方法打上断点看看
public class NioEventLoopGroup extends MultithreadEventLoopGroup {
public NioEventLoopGroup(int nThreads, Executor executor) {
this(nThreads, executor, SelectorProvider.provider());
}
@Override
protected EventLoop newChild(Executor executor, Object... args) throws Exception {
return new NioEventLoop(this, executor, (SelectorProvider) args[0],
((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2]);
}
/////////////////////////////GenericEventExecutorChooser实现next//////////////////////////////////
@Override
public EventExecutor next() {
return executors[Math.abs(idx.getAndIncrement() % executors.length)];
}
/////////////////////////////SingleThreadEventLoop实现register//////////////////////////////////
@Override
public ChannelFuture register(Channel channel) {
return register(new DefaultChannelPromise(channel, this));
}
@Override
public ChannelFuture register(final ChannelPromise promise) {
ObjectUtil.checkNotNull(promise, "promise");
promise.channel().unsafe().register(this, promise);
return promise;
}
}
我们用过程的方式来模拟NioEventLoopGroup使用
如果读者有印象netty server 至少有两组NioEventLoopGroup 一个是boss 另一个是child
public class TestBossChildGroup {
static SocketAddress address = new InetSocketAddress("localhost", 8877);
@Test
public void server() throws IOException {
SelectorProvider bossProvider = SelectorProvider.provider();
SelectorProvider childProvider = SelectorProvider.provider();
int count = 2;
AbstractSelector bossSelector = bossProvider.openSelector();
AbstractSelector[] childSelectors = new AbstractSelector[count];
for (int i = 0; i < count; i++) {
childSelectors[i] = childProvider.openSelector();
}
//server绑定访问端口 并向Selector注册OP_ACCEPT
ServerSocketChannel serverSocketChannel = bossProvider.openServerSocketChannel();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.bind(address);
serverSocketChannel.register(bossSelector, SelectionKey.OP_ACCEPT);
int i = 0;
while (true) {
int s = bossSelector.select(300);
if (s > 0) {
Set<SelectionKey> keys = bossSelector.selectedKeys();
Iterator<SelectionKey> it = keys.iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
//为什么不用elseIf 因为 key interestOps 是多重叠状态,一次返回多个操作
if (key.isAcceptable()) {
System.out.println("isAcceptable");
//这里比较巧妙,注册OP_READ交给别一个Selector处理
key.channel().register(childSelectors[i++ % count], SelectionKey.OP_READ);
}
//这部分是child eventLoop处理
if (key.isConnectable()) {
System.out.println("isConnectable");
}
if (key.isWritable()) {
System.out.println("isWritable");
}
if (key.isReadable()) {
System.out.println("isReadable");
}
key.interestOps(~key.interestOps());
it.remove();
}
}
}
}
@Test
public void client() throws IOException {
SocketChannel clientSocketChannel = SelectorProvider.provider().openSocketChannel();
clientSocketChannel.configureBlocking(true);
clientSocketChannel.connect(address);
}
}
[编织消息框架][netty源码分析]5 EventLoopGroup 实现类NioEventLoopGroup职责与实现的更多相关文章
- [编织消息框架][netty源码分析]5 eventLoop 实现类NioEventLoopGroup职责与实现
分析NioEventLoopGroup最主有两个疑问 1.next work如何分配NioEventLoop 2.boss group 与child group 是如何协作运行的 从EventLoop ...
- [编织消息框架][netty源码分析]6 ChannelPipeline 实现类DefaultChannelPipeline职责与实现
ChannelPipeline 负责channel数据进出处理,如数据编解码等.采用拦截思想设计,经过A handler处理后接着交给next handler ChannelPipeline 并不是直 ...
- [编织消息框架][netty源码分析]4 eventLoop 实现类NioEventLoop职责与实现
NioEventLoop 是jdk nio多路处理实现同修复jdk nio的bug 1.NioEventLoop继承SingleThreadEventLoop 重用单线程处理 2.NioEventLo ...
- [编织消息框架][netty源码分析]11 ByteBuf 实现类UnpooledHeapByteBuf职责与实现
每种ByteBuf都有相应的分配器ByteBufAllocator,类似工厂模式.我们先学习UnpooledHeapByteBuf与其对应的分配器UnpooledByteBufAllocator 如何 ...
- [编织消息框架][netty源码分析]8 Channel 实现类NioSocketChannel职责与实现
Unsafe是托委访问socket,那么Channel是直接提供给开发者使用的 Channel 主要有两个实现 NioServerSocketChannel同NioSocketChannel 致于其它 ...
- [编织消息框架][netty源码分析]9 Promise 实现类DefaultPromise职责与实现
netty Future是基于jdk Future扩展,以监听完成任务触发执行Promise是对Future修改任务数据DefaultPromise是重要的模板类,其它不同类型实现基本是一层简单的包装 ...
- [编织消息框架][netty源码分析]7 Unsafe 实现类NioSocketChannelUnsafe职责与实现
Unsafe 是channel的内部接口,从书写跟命名上看是不公开给开发者使用的,直到最后实现NioSocketChannelUnsafe也没有公开出去 public interface Channe ...
- [编织消息框架][netty源码分析]13 ByteBuf 实现类CompositeByteBuf职责与实现
public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements Iterable<ByteBuf ...
- [编织消息框架][netty源码分析]3 EventLoop 实现类SingleThreadEventLoop职责与实现
eventLoop是基于事件系统机制,主要技术由线程池同队列组成,是由生产/消费者模型设计,那么先搞清楚谁是生产者,消费者内容 SingleThreadEventLoop 实现 public abst ...
随机推荐
- p分位数的原理及计算
p分位数的原理及计算 大纲>> 1.统计上的分位数概念 2.分位数的计算方法及举例 2.1首先确定p分位数的位置(依据项数分为基数.偶数情况) 2.2 求上一步确定的p分位数位置处的具 ...
- Java 对系统信号的通知获取
主要介绍Java 如何对系统信号通知进行获取和处理.直接上demo @SuppressWarnings("restriction")public class Test1 imple ...
- PostgreSQL 优势,MySQL 数据库自身的特性并不十分丰富,触发器和存储过程的支持较弱,Greenplum、AWS 的 Redshift 等都是基于 PostgreSQL 开发的
PostgreSQL 优势 2016-10-20 21:36 686人阅读 评论(0) 收藏 举报 分类: MYSQL数据库(5) PostgreSQL 是一个自由的对象-关系数据库服务器(数据库 ...
- 最全的机器学习&深度学习入门视频课程集
资源介绍 链接:http://pan.baidu.com/s/1kV6nWJP 密码:ryfd 链接:http://pan.baidu.com/s/1dEZWlP3 密码:y82m 更多资源 ...
- 深入浅出写一个多级异步回调从基础到Promise实现的Demo
今天一时兴起,写了一个渐进升级的异步调用demo,记录一下. 1. 最基础的同步调用 //需求:f2在f1之后执行,且依赖f1的返回值.如下: function f1(){ var s="1 ...
- 20.multi_case03
# 多线程 import threading import time class myThread(threading.Thread): def __init__(self, threadID, na ...
- vue swiper异步加载轮播图,并且懒加载
参考:https://blog.csdn.net/weixin_38304202/article/details/78282826 效果: 此处安装省略 vue: <div class=&quo ...
- mybatis 查询sql时foreach使用法
找到俩个例子摘下来 sql查询用户in传list参数 <select id="getEmpsByConditionForeach" resultType="com. ...
- sqllocaldb
创建实例 sqllocaldb create v12.0 启动实例 sqllocaldb start v12.0
- vue中 给router-view 组件的 绑定 key 的原因
不设置 router-view 的 key 属性 由于 Vue 会复用相同组件, 即 /page/1 => /page/2 或者 /page?id=1 => /page?id=2 这类链接 ...