一、基础铺垫
1. JAVA中的基本位运算符
运算符 | 描述 |
---|---|
& | 与 |
| | 或 |
~ | 非 |
^ | 异或 |
<< | 左移 |
>> | 右移 |
2. 位运算解释与实例
&(与)
十进制 | 二进制 |
---|---|
3 | 0 0 1 1 |
5 | 0 1 0 1 |
& 后结果:1 | 0 0 0 1 |
即:对应位都为 1 时,才为 1,否则全为 0。
|(或)
十进制 | 二进制 |
---|---|
3 | 0 0 1 1 |
5 | 0 1 0 1 |
| 后结果 :7 | 0 1 1 1 |
即:对应位只要有 1 时,即为 1,否则全为 0。
~(非)
十进制 | 二进制 |
---|---|
3 | 0 0 1 1 |
~ 后结果:12 | 1 1 0 0 |
即:对应位取反。
异或 ^
十进制 | 二进制 |
---|---|
3 | 0 0 1 1 |
5 | 0 1 0 1 |
^ 后结果:6 | 0 1 1 0 |
即:只要对应为不同即为 1。
3. 配合Netty实例
我们在以往学习Netty中见到过类似于以下代码:
selectionKey.interestOps(interestOps | readInterestOp);
复制代码
我们重点关注位运算:interestOps | readInterestOp
该行代码的意思是位运算计算一个数字,该数字包含 | 前后的数字!
//初始化一个值
int interestOps = 0;
//给当前这个值增加一个可读事件
interestOps |= OP_READ;
//给当前的值增加一个可写的事件
interestOps |= OP_WRITE;
//判断当前的事件是不是包含可读事件 true
boolean isRead = (interestOps & OP_READ) == OP_READ;
//判断当前的事件是不是不包含可读事件 false
boolean isRead = (interestOps & OP_READ) == 0;
//剔除可读事件
interestOps &= ~OP_READ;
//剔除可写事件
interestOps &= ~OP_WRITE;
复制代码
二、源码解析
1. 创建管道
io.netty.channel.DefaultChannelPipeline#DefaultChannelPipeline
protected DefaultChannelPipeline(Channel channel) {
this.channel = ObjectUtil.checkNotNull(channel, "channel");
succeededFuture = new SucceededChannelFuture(channel, null);
voidPromise = new VoidChannelPromise(channel, true);
//创建一个管道上下文 尾部节点
tail = new TailContext(this);
//创建一个管道上下文 头部节点
head = new HeadContext(this);
//头部节点的下一个节点设置为尾部节点
head.next = tail;
//尾部节点的上一个节点设置为头部节点
tail.prev = head;
}
复制代码
可以看到,这里初始化管道的时候,管道内部存在两个Handler tail和head节点,两个节点组成双向链表!
2. 向通道内添加一个Handler处理器
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("channelRegistered");
super.channelRegistered(ctx);
}
});
复制代码
上述代码再一个Netty开发中是很常见的一个代码,这里向通道内添加了一个 ChannelInboundHandlerAdapter
,我们进入到addLast方法:
@Override
public final ChannelPipeline addLast(ChannelHandler... handlers) {
return addLast(null, handlers);
}
//进入到 addLast
@Override
public final ChannelPipeline addLast(EventExecutorGroup executor, ChannelHandl