AbstractChannel-register方法详解

95-30-010-Channel-AbstractChannel 文章目录1. 概述2. 类图3. AbstractChannel3.1 私有字段3.2 构造方法3.3 register事件框架3.4 bind事件框架3.5 disconnect事件框架3.6 close事件框架3.7 deregister事件框架3.8 write事件框架3.9 flush事件框架 1. 概述 2. 类图 3. AbstractChannel 3.1 私有字段 首先看其中的字段: private final Channel parent; // 父Channel pri 阅读详情

AbstractChannel.register() 方法详解

一、方法概述

register() 方法位于 AbstractUnsafe 内部类中,负责将 Channel 注册到 EventLoop 上。这是 Netty 启动过程中的关键步骤。

二、方法签名

@Override
public final void register(EventLoop eventLoop, final ChannelPromise promise)

参数说明:

  • eventLoop: 要注册到的事件循环,Channel 的所有 I/O 操作都将在这个线程中执行
  • promise: 异步操作的结果承诺,用于通知注册操作的成功或失败

三、方法执行流程

3.1 参数校验阶段

if (eventLoop == null) {
    throw new NullPointerException("eventLoop");
}
if (isRegistered()) {
    promise.setFailure(new IllegalStateException("registered to an event loop already"));
    return;
}
if (!isCompatible(eventLoop)) {
    promise.setFailure(
        new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName()));
    return;
}

校验内容:

  1. EventLoop 非空检查:确保传入的 EventLoop 不为 null
  2. 重复注册检查:如果 Channel 已经注册过,直接失败返回
  3. 兼容性检查:验证 EventLoop 类型是否与当前 Channel 兼容
    • 例如:NioSocketChannel 需要 NioEventLoop

3.2 绑定 EventLoop

AbstractChannel.this.eventLoop = eventLoop;

关键点:

  • 将 EventLoop 赋值给 Channel 的成员变量
  • 从此刻起,Channel 与这个 EventLoop 绑定
  • Channel 的整个生命周期都将在这个 EventLoop 的线程中执行

3.3 线程判断与任务提交

if (eventLoop.inEventLoop()) {
    register0(promise);
} else {
    try {
        eventLoop.execute(new Runnable() {
            @Override
            public void run() {
                register0(promise);
            }
        });
    } catch (Throwable t) {
        logger.warn(
            "Force-closing a channel whose registration task was not accepted by an event loop: {}",
            AbstractChannel.this, t);
        closeForcibly();
        closeFuture.setClosed();
        safeSetFailure(promise, t);
    }
}

线程安全保证:

这是 Netty 线程模型的核心体现:

  1. 如果当前线程就是 EventLoop 线程:

    • 直接调用 register0(promise) 执行注册
    • 避免不必要的线程切换
  2. 如果当前线程不是 EventLoop 线程:

    • 将注册任务封装成 Runnable
    • 提交到 EventLoop 的任务队列中
    • EventLoop 线程会异步执行这个任务
    • 这保证了所有 Channel 操作都在同一个线程中执行,避免并发问题
  3. 异常处理:

    • 如果任务提交失败(如 EventLoop 已关闭)
    • 强制关闭 Channel
    • 设置 Promise 失败状态

四、register0() 核心注册逻辑

private void register0(ChannelPromise promise) {
    try {
        // 1. 检查 Channel 是否仍然打开
        if (!promise.setUncancellable() || !ensureOpen(promise)) {
            return;
        }
        
        // 2. 记录是否首次注册
        boolean firstRegistration = neverRegistered;
        
        // 3. 执行实际的注册操作(模板方法,由子类实现)
        doRegister();
        
        // 4. 更新注册状态
        neverRegistered = false;
        registered = true;
        
        // 5. 触发 handlerAdded 事件
        pipeline.invokeHandlerAddedIfNeeded();
        
        // 6. 设置 Promise 成功
        safeSetSuccess(promise);
        
        // 7. 触发 channelRegistered 事件
        pipeline.fireChannelRegistered();
        
        // 8. 如果 Channel 已激活,触发 channelActive 事件
        if (isActive()) {
            if (firstRegistration) {
                pipeline.fireChannelActive();
            } else if (config().isAutoRead()) {
                // 如果是重新注册且开启了自动读取,开始读取数据
                beginRead();
            }
        }
    } catch (Throwable t) {
        // 注册失败,强制关闭 Channel
        closeForcibly();
        closeFuture.setClosed();
        safeSetFailure(promise, t);
    }
}

4.1 关键步骤详解

步骤 1:Promise 状态检查
if (!promise.setUncancellable() || !ensureOpen(promise)) {
    return;
}
  • 设置 Promise 为不可取消状态
  • 确保 Channel 仍然是打开状态
  • 如果 Channel 已关闭,直接返回
步骤 2-4:执行注册并更新状态
boolean firstRegistration = neverRegistered;
doRegister();  // 调用子类实现,如 NioSocketChannel 会将 Channel 注册到 Selector
neverRegistered = false;
registered = true;

doRegister() 示例(NioSocketChannel):

@Override
protected void doRegister() throws Exception {
    boolean selected = false;
    for (;;) {
        try {
            // 将 Java NIO Channel 注册到 Selector,ops=0 表示暂不关注任何事件
            selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this);
            return;
        } catch (CancelledKeyException e) {
            // 处理异常...
        }
    }
}
步骤 5:触发 handlerAdded 事件
pipeline.invokeHandlerAddedIfNeeded();
  • 调用 Pipeline 中所有 Handler 的 handlerAdded() 方法
  • 这是 Handler 初始化的时机
步骤 6-7:通知注册成功
safeSetSuccess(promise);
pipeline.fireChannelRegistered();
  • 设置 Promise 为成功状态,通知调用者
  • 触发 channelRegistered 事件,在 Pipeline 中传播
步骤 8:处理 Channel 激活状态
if (isActive()) {
    if (firstRegistration) {
        pipeline.fireChannelActive();
    } else if (config().isAutoRead()) {
        beginRead();
    }
}

两种情况:

  1. 首次注册且 Channel 已激活(如服务端绑定端口后):

    • 触发 channelActive 事件
    • 这会导致 Pipeline 中的 Handler 开始处理连接
  2. 重新注册且开启自动读取:

    • 调用 beginRead() 开始读取数据
    • 这处理了 Channel 注销后重新注册的场景

五、时序图

调用者线程                EventLoop线程              Selector
    |                         |                        |
    |--register(eventLoop)--->|                        |
    |                         |                        |
    |  判断当前线程            |                        |
    |  不是EventLoop线程       |                        |
    |                         |                        |
    |--execute(task)--------->|                        |
    |                         |                        |
    |                         |--register0()           |
    |                         |                        |
    |                         |--doRegister()--------->|
    |                         |                        |
    |                         |<-注册成功--------------|
    |                         |                        |
    |                         |--invokeHandlerAdded()  |
    |                         |                        |
    |                         |--fireChannelRegistered()|
    |                         |                        |
    |                         |--fireChannelActive()   |
    |                         |                        |
    |<--promise.setSuccess()--|                        |

六、关键设计模式

6.1 模板方法模式

  • register() 定义了注册的骨架流程
  • doRegister() 由子类实现具体的注册逻辑

6.2 责任链模式

  • 通过 Pipeline 传播事件:fireChannelRegistered()、fireChannelActive()

6.3 异步回调模式

  • 使用 ChannelPromise 异步通知注册结果

七、常见问题

Q1: 为什么要判断 eventLoop.inEventLoop()?

A: 这是 Netty 线程模型的核心保证:

  • 所有 Channel 操作必须在其绑定的 EventLoop 线程中执行
  • 避免多线程并发问题
  • 如果当前线程不是 EventLoop 线程,需要将任务提交到 EventLoop 执行

Q2: doRegister() 为什么注册时 ops=0?

A:

  • 注册时不关注任何事件,避免在 Handler 未完全初始化时就触发事件
  • 等到 channelActive 事件触发后,才会注册感兴趣的事件(如 OP_READ)

Q3: 什么时候会触发 channelActive?

A:

  • 服务端:bind() 成功后,Channel 变为 Active 状态
  • 客户端:connect() 成功后,Channel 变为 Active 状态

Q4: 为什么有 firstRegistration 判断?

A:

  • Channel 可能会注销后重新注册(如切换 EventLoop)
  • 首次注册需要触发 channelActive 事件
  • 重新注册只需要恢复读取操作,不需要重复触发 channelActive

八、实际应用场景

场景 1:服务端启动

ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
 .channel(NioServerSocketChannel.class)
 .childHandler(new ChannelInitializer<SocketChannel>() {
     @Override
     public void initChannel(SocketChannel ch) {
         // 当 register() 完成后,会触发 handlerAdded
         // 然后执行这里的初始化代码
     }
 });

ChannelFuture f = b.bind(port).sync();
// bind() 内部会调用 register()

场景 2:客户端连接

Bootstrap b = new Bootstrap();
b.group(group)
 .channel(NioSocketChannel.class)
 .handler(new ChannelInitializer<SocketChannel>() {
     @Override
     public void initChannel(SocketChannel ch) {
         // register() 完成后触发
     }
 });

ChannelFuture f = b.connect(host, port).sync();
// connect() 内部会先调用 register()

九、总结

register() 方法是 Netty 启动流程中的关键环节:

  1. 线程安全:确保所有操作在 EventLoop 线程中执行
  2. 状态管理:维护 Channel 的注册状态
  3. 事件传播:触发 Pipeline 中的事件流转
  4. 资源绑定:将 Channel 与 EventLoop、Selector 绑定
MATLAB极坐标伪彩色圆图绘制之polarPcolor函数 polarPcolor函数介绍 我们经常在论文或期刊上看到如下图这种以色调冷暖代表数值大小的极坐标圆图, 而function [varargout] = polarPcolor(R,theta,Z,varargin)可以很好的帮助我们快速绘制这类极坐标圆图。它非常适合雷达或激光雷达的平面位置指示器。使用polarPcolor函数时,我们只需根据手中数据构造相应的二维矩阵Z即可,十分便捷。varargin值为绘制模式选择。R值为半径坐标一维矩阵,theta值为角坐标一维矩阵。 代码示例 这里使用了海洋表面耀光 阅读详情

相关推荐

VMware 虚拟机里连不上网的五种解决方案

在VMware虚拟机里的虚拟机系统连接不上网络 首先,注意查看适配器选项里的网络连接这两个网络连接是否存在,如果不存在可以重新装一下VM 如果存在,连不上网 解决办法一: 虚拟机设置里,找到“网络适配器”,右边的网络连接选择“NAT 模式”,如果不行的话再linux系统。还是不行的话接着看第二种解决方案。 解决方法二: 可能原因是VMware NET Service...

墨轩 18万+

Netty源码分析---register0方法详解

摘要:本文详细解析了Netty中AbstractChannel.register0()方法的实现机制。该方法负责将Channel注册到EventLoop的核心流程,包括Selector注册、状态更新和事件触发。关键点包括:1) 确保在EventLoop线程执行;2) 通过doRegister()完成底层Selector注册;3) 触发handlerAdded和channelRegistered事件;4) 根据首次注册状态决定是否触发channelActive事件。该方法还包含完善的异常处理机制,是Netty

java_rutu的博客 531

MIUI升级后录音神秘消失?别慌!手把手教你从Android/data目录找回宝贵录音文件

本文详细解析了MIUI升级后录音文件消失的原因,并提供了从Android/data目录找回录音文件的实用指南。通过技术分析和步骤演示,帮助小米手机用户解决录音文件丢失问题,同时分享预防措施和高级恢复方案,确保重要录音数据安全。

weixin_30696427的博客 281

Netty源码解析之ServerSocketChannel register流程

阅读须知 Netty版本:4.1.14.Final 文章中使用/**/注释的方法会做深入分析 正文 我们在分析Bootstrap引导启动的源码时看到了Channel的注册,但是并没有做深入分析,本篇文章我们就来看一下Channel的注册流程。Channel的注册委托给了Channel内部的Unsafe来完成,我们来看实现: AbstractChannel.AbstractUnsafe...

0xZzzz的博客 2913

ESP32连接OneNet云平台实现多设备联动控制完整示例

通过esp32连接onenet云平台,实现远程设备间的智能联动控制,利用MQTT协议完成数据通信,esp32连接onenet云平台后可高效稳定地上传与下发指令,提升物联网系统响应速度与自动化水平。

weixin_42360733的博客 548

【Pandas总结】第二节 Pandas 的数据读取_pd.read_csv()的使用详解(非常全面,推荐收藏)

pandas对纯文本的读取提供了非常强力的支持,参数有四五十个。这些参数中,有的很容易被忽略,但是在实际工作中却用处很大。

weixin_47139649的博客 11万+

netty源码解析(4.0)-3 Channel的抽象实现

AbstractChannel和AbstractUnsafe抽象类 io.netty.channel.AbstractChannel 从本章开始,会有大量的篇幅涉及到代码分析。为了能够清晰简洁的地说明代码的结构和功能,我会用代码注释+独立段落的方式加以呈现。 所以,为你能更好地理解代码,请不要忽略代码中黑体字注释。 AbstractChannel和AbstractUnsafe之间的关系...

自带buff 2057

【占用网络】OccNet: Scene as Occupancy 适用于检测、分割和规划任务 ICCV2023

本文分享“占用网络”方案中,具有代表性的方法:OccNet。它以多视角视觉为核心,首先生成BEV特征,然后通过级联结构和时间体素解码器重建生成3D占用特征。构建一个通用的“3D占用编码特征”,用以表示3D物理世界。这样的特征描述可以应用于广泛的自动驾驶任务,包括检测、分割和规划。

黎国溥 3362

Bootstrap的register

业务代码 // Start the server. ChannelFuture f = b.bind(PORT).sync(); AbstractBootstrap public ChannelFuture bind(SocketAddress localAddress) { validate(); if (localAddress == null) { throw new NullPointerException("localAddress

kongkong的专栏 833

FFmpeg入门详解之110:RTSP协议讲解

TCP/IP 协议体系中的一个应用层协议,该协议定义了一对多应用程序如何有效地通过 IP 网络传送多媒体数据。RTSP在体系结构上位于RTP和RTCP之上,它使用TCP或UDP完成数据传输。HTTP与RTSP相比,HTTP传送HTML,而RTSP传送的是多媒体数据。正在上传…重新上传取消RTSP是基于文本的协议,采用ISO10646字符集,使用UTF-8编码方案。行以CRLF中断(\r\n:10,13:0x0A,0x0D),包括消息类型、消息头、消息体和消息长。

福优学苑@音视频+流媒体 2529

钢结构焊接连接工艺

钢结构焊接连接工艺

wwdoffice950426的博客 61

EventLoop 与Channel 的关联

在Netty 中, 每个Channel 都有且仅有一个EventLoop 与之关联, 它们的关联过程如下: 从上图中我们可以看到,当调用AbstractChannel$AbstractUnsafe.register()方法后,就完成了Channel 和EventLoop的关联。register()方法的具体实现如下: public final void register(EventLoop eventLoop, final ChannelPromise promise) { // 删除条件检查

Leon_Jinhai_Sun的博客 608

【数据集】中国2003年至2022年全天空每日气温数据集

中国2003年至2022年全天空每日气温数据集

WW、forever的博客 603

netty2-> 扒一扒register

入口还是initAndRegister final ChannelFuture initAndRegister() { Channel channel = null; try { channel = channelFactory.newChannel(); init(channel); }...

u013657993的专栏 427

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Netty源码分析第1章(Netty启动流程)---->第4节: 注册多路复用

Netty源码分析第1章(Netty启动流程)---->第4节: 注册多路复用 Netty源码分析第一章:Netty启动流程 第四节:注册多路复用 回顾下以上的小节, 我们知道了channel的的创建和初始化过程, 那么channel是如何注册到selector中的呢?我们继续分析 回到上一小节的代码: fi...

weixin_30567225的博客 107

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Netty-parentGroup线程启动时刻

前言:其实掌握Netty的源码不难,关键是掌握几个点,本文介绍其中一个,parentGroup线程在哪启动? 流程1:AbstractChannel.register(EventLoop eventLoop, final ChannelPromise promise)方法 流程2:SingleThreadEventExecutor.execute(Runnable task)方法 流程3:SingleThreadEventExecutor.startThread()方法 流程4:SingleThrea

weixin_42002747的博客 665

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Netty教程(二)-服务端启动(二)——注册selector和端口绑定

https://juejin.cn/post/6887395440619651080 接上篇Netty服务端启动(一)——创建和初始化channel 注册selector 先概括一下,主要做了这几件事 设置eventloop(用于绑定线程) 调用jdk底层的SelectableChannel类的register方法进行注册 触发handler被添加到channel上的回调,触发channel注册成功事件 注册selector的过程就在config().group().register(ch.

yygr的博客 461

Netty源码阅读(八): NioServerSocketChannel源码解析

先看一下NioServerSocketChannel的继承结构。 AttributeMap接口及DefaultAttributeMap主要是提供了体检属性和获取属性的能力,便于我们为Channel绑定额外的属性。 AbstractChannel实现了Channel接口,实现了Channel通用的行为和方法,我们在Netty学习系列四中已经介绍过了。 AbstractNioC...

scofen的博客 454

netty源码解解析(4.0)-3 Channel的抽象实现

AbstractChannel和AbstractUnsafe抽象类 io.netty.channel.AbstractChannel 从本章开始,会有大量的篇幅涉及到代码分析。为了能够清晰简洁的地说明代码的结构和功能,我会用代码注释+独立段落的方式加以呈现。 所以,为你能更好地理解代码,请不要忽略代码中黑体字注释。 AbstractChannel和AbstractUnsafe之间的关系...

weixin_30387663的博客 338

【Netty源码解析和权威指南】第14篇:Netty Channel源码解析(上)—— 网络I/O的抽象艺术

本文深入解析Netty Channel的设计原理和实现机制,作为网络I/O的核心抽象层,Channel统一了不同协议和传输方式的编程模型。文章通过对比Java NIO Channel,展现Netty Channel在易用性、功能丰富度和线程模型集成等方面的优势。重点剖析了Channel的继承体系,包括顶层接口、抽象类和具体实现类(如NioSocketChannel)。详细讲解核心API的使用方法,包括连接管理、数据读写和状态查询等,并附实战代码示例。Channel通过抽象网络I/O操作,大幅简化了网络编程复

xyghehehehe的专栏 90

netty源码阅读之客户端新连接之读事件的注册

上一篇文章《netty源码阅读之客户端新连接之分配线程并注册selector》这里,我们最后分析到AbstractChannel的register0()的代码: private void register0(ChannelPromise promise) { try { // check if the channel is...

翻身咸鱼的博客 722

netty源码阅读--服务启动

netty源码阅读

sinat_28771747的博客 672

EventLoop 与 Channel 的关联

Netty 中, 每个 Channel 都有且仅有一个 EventLoop 与之关联, 它们的关联过程如下: 从上图中我们可以看到, 当调用了 AbstractChannel#AbstractUnsafe.register 后, 就完成了 Channel 和 EventLoop 的关联. register 实现如下: @Override public final void registe...

weixin_34015860的博客 481

DefaultChannelPipeline之channelActive

register0 入口 AbstractChannel.register0 private void register0(ChannelPromise promise) { try { .................. boolean firstRegistration = neverRegistered; doRegister(); neverRegi

kongkong的专栏 700

netty源码之NioEventLoop

目录 一、初始化 1、NioEventLoopGroup最终都是调用父类MultithreadEventLoopGroup的构造器 2、通过父类MultiThreadEventExecutorGroup构造器创建NioEventLoopGroup实例,内部维护了一个SingleThreadEventExecutor类型的数组,通过newChild()方法进行实例化 3、newChild()方法实例化的是NioEventLoop类型的EventLoop对象 4、NioEventLoop 打开一个se

u012391423的博客 349
上一篇: ChannelHandler深度解析-核心机制与工作原理
下一篇: Netty源码分析---ChannelInitializer工作原理详解
不早睡不改名@
博客等级 码龄5年 536粉丝 306原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值