Netty中的异步串行无锁化

在Netty源码中很多地方都会调用一个叫做inEventLoop()的方法, 这个方法的作用是啥呢?
在NioEventLoop中封装了一个线程, 这个线程我们叫它IO线程.

private volatile Thread thread;

这个IO线程就是用来处理客户端的连接事件, 读写事件, 还有一个重要的事情也是由这个IO线程去做的, 是啥呢? 就是处理队列中的任务. 没错, 每个NioEventLoop都有一个队列, 这个队列是在创建NioEventLoop时被初始化

taskQueue = newTaskQueue(this.maxPendingTasks);
@Override
protected Queue<Runnable> newTaskQueue(int maxPendingTasks) {
    
	return maxPendingTasks == Integer.MAX_VALUE ? PlatformDependent.<Runnable>newMpscQueue()
                                                    : PlatformDependent.<Runnable>newMpscQueue(maxPendingTasks);
}

这个队列的具体实现简单说就是多个生产者单个消费者, 要不为啥叫Mp(producer)s(single)c(consumer)呢.

现在看来就比较明朗了, 其他的线程, 也就是多个生产者, 如果需要进行读写操作, 就把读写操作封装成任务放在这个队列中, 然后由这个NioEventLoop封装的IO线程去消费. 当然这个队列的设计是线程安全的, 否则就出问题了.

那么假如现在有一个线程, 它咋知道我是该主动去执行读写操作, 还是应该把自己的读写操作封装成任务放在队列中呢? 那么它就会去调用一下inEventLoop()方法, 这个方法会返回一个boolean值告诉它. 其实这个方法的实现很简单

@Override
public boolean inEventLoop() {
	return inEventLoop(Thread.currentThread());
}

@Override
public boolean inEventLoop(Thread thread) {
	return thread == this.thread;
}

从源码中可以看出来, 它就是拿当前线程和之前创建NioEventLoop时绑定的那个IO线程进行判断, 如果是一样的, 说明此线程就是绑定的IO线程, 可以执行读写操作, 如果不一样, 那么说明是其他线程, 就要把读写操作封装成任务放在队列中, 由绑定的那个IO线程去执行.

这也是Netty设计的异步串行无锁化. 在Netty中线程之间不用同步控制, 可以做到线程安全.

微信公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值