Netty学习之旅------图说Netty线程模型

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

=============

提到Netty的线程模型,我们不得不再重复提到主从Reactor线程模型,Netty线程模型基本上基于主从Reactor模型的实现方式,Netty线程模型将从如下两个图进行展开:

Reactor 主从线程模型

Netty服务端示例代码。

关于Reactor主从多线程模型的讲解,请重点关注Netty 线程模型前置篇,Reactor主从模式源码实现,从Netty服务端示例代码可以看出,Netty的线程模型,必然与EventLoopGroup脱离不了干系。不错,上文中的bossGroup就是相当与Reactor模式中的Main Reactor,而workGroup,则相当于SubReactor。

Netty线程模型类层次结构:

Netty线程模型类继承图:

从如上图可以知道,Netty的线程模型,中有4个基础接口,它们分别是EventLoopGroup、EventLoop、EventExecuteGroup、EventExecute。其中EventExecute扩展自java.util.concurrent.ScheduledExecutorService接口,类似与线程池(执行)的职责,而EventLoop首先继承自EventExecute,并主要扩展了register方法,就是将通道Channel注册到Selector的方法。

NioEventLoop,就是基于Nio的实现。在这个类中有一个亮点,就是规避了JDK nio的一个bug,Selector select方法的空轮询,核心思想是,如果连续多少次(默认为512)在没有超时的情况就返回,并且已经准备就绪的键的数量为0,则认为发生了空轮询,如果发生了空轮询,就新建一个新的Selector,并重新将通道,关心的事件注册到新的Selector,并关闭旧的Selector,其源码实现如下:

private void select(boolean oldWakenUp) throws IOException {

Selector selector = this.selector;

try {

int selectCnt = 0;

long currentTimeNanos = System.nanoTime();

long selectDeadLineNanos = currentTimeNanos + delayNanos(currentTimeNanos);

for (;😉 {

long timeoutMillis = (selectDeadLineNanos - currentTimeNanos + 500000L) / 1000000L;

if (timeoutMillis <= 0) {

if (selectCnt == 0) {

selector.selectNow();

selectCnt = 1;

}

break;

}

int selectedKeys = selector.select(timeoutMillis);

selectCnt ++;

if (selectedKeys != 0 || oldWakenUp || wakenUp.get() || hasTasks() || hasScheduledTasks()) {

// - Selected something,

// - waken up by user, or

// - the task queue has a pending task.

// - a scheduled task is ready for processing

break;

}

if (Thread.interrupted()) {

// Thread was interrupted so reset selected keys and break so we not run into a busy loop.

// As this is most likely a bug in the handler of the user or it’s client library we will

// also log it.

//

// See https://github.com/netty/netty/issues/2426

if (logger.isDebugEnabled()) {

logger.debug("Selector.select() returned prematurely because " +

"Thread.currentThread().interrupt() was called. Use " +

“NioEventLoop.shutdownGracefully() to shutdown the NioEventLoop.”);

}

selectCnt = 1;

break;

}

long time = System.nanoTime();

if (time - TimeUnit.MILLISECONDS.toNanos(timeoutMillis) >= currentTimeNanos) {

// timeoutMillis elapsed without anything selected.

selectCnt = 1;

} else if (SELECTOR_AUTO_REBUILD_THRESHOLD > 0 &&

selectCnt >= SELECTOR_AUTO_REBUILD_THRESHOLD) {

// The selector returned prematurely many times in a row.

// Rebuild the selector to work around the problem.

logger.warn(

“Selector.select() returned prematurely {} times in a row; rebuilding selector.”,

selectCnt);

rebuildSelector();

selector = this.selector;

// Select again to populate selectedKeys.

selector.selectNow();

selectCnt = 1;

break;

}

currentTimeNanos = time;

}

if (selectCnt > MIN_PREMATURE_SELECTOR_RETURNS) {

if (logger.isDebugEnabled()) {

logger.debug(“Selector.select() returned prematurely {} times in a row.”, selectCnt - 1);

}

}

} catch (CancelledKeyException e) {

if (logger.isDebugEnabled()) {

logger.debug(CancelledKeyException.class.getSimpleName() + " raised by a Selector - JDK bug?", e);

}

// Harmless exception - log anyway

}

}

/**

  • Replaces the current {@link Selector} of this event loop with newly created {@link Selector}s to work

  • around the infamous epoll 100% CPU bug.

*/

public void rebuildSelector() {

if (!inEventLoop()) {

execute(new Runnable() {

@Override

public void run() {

rebuildSelector();

}

});

return;

}

final Selector oldSelector = selector;

final Selector newSelector;

if (oldSelector == null) {

return;

}

try {

newSelector = openSelector();

} catch (Exception e) {

logger.warn(“Failed to create a new Selector.”, e);

return;

}

最后

面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典

  • Java核心知识整理

2020年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多

Java核心知识

  • Spring全家桶(实战系列)

2020年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多

  • 其他电子书资料

2020年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多

Step3:刷题

既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。

以下是我私藏的面试题库:

2020年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
]

Step3:刷题

既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。

以下是我私藏的面试题库:

[外链图片转存中…(img-QesAicGb-1714641789779)]
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

  • 19
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值