Netty源码分析---NioServerSocketChannel-Unsafe初始化详解

netty源码分析3-NioServerSocketChannel,NioSocketChannel 本文分析内容如下 Channel主要接口分析 AbstractChannel分析 AbstractNioChannel分析 AbstractNioByteChannel分析 AbstractNioMessageChannel 分析 NioSocketChannel分析 AbstractNioMessageServerChannel分析 NioServerSocketChannel分... 阅读详情

相关文章链接

位运算详解

waken方法详解

ThreadPerTaskExecutor与线程创建详解

processSelectedKeys() vs runAllTasks()

NioServerSocketChannel-Unsafe初始化详解

NioEventLoop的run方法详解

NioEventLoopGroup深度解析

inEventLoop方法详解

executionMask详解

Netty源码分析–认真系列(一)

Netty源码分析–认真系列(二)

NioServerSocketChannel Unsafe 初始化详解

问题

在 Netty 服务端启动过程中,NioServerSocketChannel 的 unsafe 字段到底是什么类型?为什么是这个类型?

答案

NioServerSocketChannel 的 unsafe 字段是 NioMessageUnsafe 类型的实例。

本文档将从构造函数开始,逐步追踪代码,解释这个结论是如何得出的。


前置知识:类继承关系

在开始追踪代码之前,先了解 NioServerSocketChannel 的继承关系:

AbstractChannel (最顶层父类)
    ↑ 继承
AbstractNioChannel
    ↑ 继承
AbstractNioMessageChannel (实现了 newUnsafe() 方法)
    ↑ 继承
NioServerSocketChannel (我们创建的类)

关键点:

  • AbstractChannel 定义了 unsafe 字段
  • AbstractChannel 定义了抽象方法 newUnsafe()
  • AbstractNioMessageChannel 实现了 newUnsafe() 方法

代码追踪:从构造函数到 unsafe 初始化

步骤 1:创建 NioServerSocketChannel 对象

// ServerBootstrap 启动时
Channel channel = new NioServerSocketChannel();

这行代码会触发 NioServerSocketChannel 的构造方法。


步骤 2:NioServerSocketChannel 无参构造方法

位置:io.netty.channel.socket.nio.NioServerSocketChannel

public class NioServerSocketChannel extends AbstractNioMessageChannel 
                                    implements ServerSocketChannel {
    
    private static final SelectorProvider DEFAULT_SELECTOR_PROVIDER = 
        SelectorProvider.provider();
    
    // 【入口】无参构造方法
    public NioServerSocketChannel() {
        // 调用本类的另一个构造方法
        this(newSocket(DEFAULT_SELECTOR_PROVIDER));
    }
    
    // 创建 Java NIO 的 ServerSocketChannel
    private static ServerSocketChannel newSocket(SelectorProvider provider) {
        try {
            return provider.openServerSocketChannel();
        } catch (IOException e) {
            throw new ChannelException("Failed to open a server socket.", e);
        }
    }
}

说明:

  • 调用 newSocket() 创建 Java NIO 的 ServerSocketChannel
  • 然后调用本类的重载构造方法

步骤 3:NioServerSocketChannel 有参构造方法

位置:io.netty.channel.socket.nio.NioServerSocketChannel

public NioServerSocketChannel(ServerSocketChannel channel) {
    // 调用父类 AbstractNioMessageChannel 的构造方法
    // 参数:parent=null, channel=ServerSocketChannel, readInterestOp=OP_ACCEPT
    super(null, channel, SelectionKey.OP_ACCEPT);
    
    // 创建配置对象(与 unsafe 无关,略过)
    config = new NioServerSocketChannelConfig(this, javaChannel().socket());
}

说明:

  • 调用父类 AbstractNioMessageChannel 的构造方法
  • 传入 OP_ACCEPT 表示关注接受连接事件

步骤 4:AbstractNioMessageChannel 构造方法

位置:io.netty.channel.nio.AbstractNioMessageChannel

public abstract class AbstractNioMessageChannel extends AbstractNioChannel {
    
    protected AbstractNioMessageChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
        // 继续调用父类 AbstractNioChannel 的构造方法
        super(parent, ch, readInterestOp);
    }
}

说明:

  • 这个类没有做额外处理,直接调用父类构造方法
  • 注意:这个类后面会实现 newUnsafe() 方法(见步骤 7)

步骤 5:AbstractNioChannel 构造方法

位置:io.netty.channel.nio.AbstractNioChannel

public abstract class AbstractNioChannel extends AbstractChannel {
    
    private final SelectableChannel ch;
    protected final int readInterestOp;
    
    protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
        // 继续调用父类 AbstractChannel 的构造方法
        super(parent);
        
        // 保存 Java NIO 的 Channel
        this.ch = ch;
        this.readInterestOp = readInterestOp;
        
        try {
            // 设置为非阻塞模式
            ch.configureBlocking(false);
        } catch (IOException e) {
            // ... 异常处理
        }
    }
}

说明:

  • 保存 Java NIO 的 SelectableChannel
  • 设置为非阻塞模式
  • 继续调用父类 AbstractChannel 的构造方法

步骤 6:AbstractChannel 构造方法(核心!)

位置:io.netty.channel.AbstractChannel

public abstract class AbstractChannel extends DefaultAttributeMap implements Channel {
    
    private final Channel parent;
    private final ChannelId id;
    private final Unsafe unsafe;  // unsafe 字段在这里定义
    private final DefaultChannelPipeline pipeline;
    
    protected AbstractChannel(Channel parent) {
        this.parent = parent;
        
        // 创建唯一 ID
        id = newId();
        
        // 【核心】调用 newUnsafe() 方法创建 unsafe 实例
        unsafe = newUnsafe();
        
        // 创建 Pipeline
        pipeline = newChannelPipeline();
    }
    
    // 抽象方法,由子类实现
    protected abstract AbstractUnsafe newUnsafe();
    
    protected ChannelId newId() {
        return DefaultChannelId.newInstance();
    }
    
    protected DefaultChannelPipeline newChannelPipeline() {
        return new DefaultChannelPipeline(this);
    }
}

说明:

  • unsafe 字段在这里被初始化
  • 调用 newUnsafe() 方法创建实例
  • newUnsafe() 是抽象方法,需要子类实现

关键问题:这里调用的是哪个类的 newUnsafe() 方法?


步骤 7:多态机制 - 实际调用的是哪个 newUnsafe()?

虽然 newUnsafe() 方法在 AbstractChannel 中被调用,但是:

当前对象的实际类型是 NioServerSocketChannel!

让我们看看继承链上哪个类实现了 newUnsafe() 方法:

AbstractChannel(定义抽象方法)
protected abstract AbstractUnsafe newUnsafe();
AbstractNioChannel(没有实现)
// 这个类没有实现 newUnsafe() 方法
AbstractNioMessageChannel(实现了!)

位置:io.netty.channel.nio.AbstractNioMessageChannel

public abstract class AbstractNioMessageChannel extends AbstractNioChannel {
    
    @Override
    protected AbstractNioUnsafe newUnsafe() {
        // 返回 NioMessageUnsafe 实例
        return new NioMessageUnsafe();
    }
}

找到了! AbstractNioMessageChannel 实现了 newUnsafe() 方法。

NioServerSocketChannel(没有重写)
// 这个类没有重写 newUnsafe() 方法
// 所以使用父类 AbstractNioMessageChannel 的实现

步骤 8:Java 多态机制详解

为什么调用的是 AbstractNioMessageChannel.newUnsafe()?

这是 Java 的多态机制决定的。让我们用一个简单的例子说明:

// 类比例子
class Animal {
    void init() {
        sound = makeSound();  // 调用抽象方法
    }
    abstract String makeSound();
}

class Dog extends Animal {
    @Override
    String makeSound() {
        return "汪汪";  // Dog 实现了 makeSound
    }
}

// 创建对象
Animal animal = new Dog();  // 实际类型是 Dog
// 虽然 init() 方法在 Animal 类中
// 但 makeSound() 调用的是 Dog 的实现

对应到 Netty:

// 创建对象
new NioServerSocketChannel();

// 调用链路
NioServerSocketChannel 构造
  ↓
AbstractNioMessageChannel 构造
  ↓
AbstractNioChannel 构造
  ↓
AbstractChannel 构造
  ↓
unsafe = newUnsafe();  // 在 AbstractChannel 中调用

关键点:

  1. 虽然 newUnsafe() 在 AbstractChannel 中被调用
  2. 但当前对象的实际类型是 NioServerSocketChannel
  3. Java 虚拟机会从实际类型开始,向上查找 newUnsafe() 的实现
  4. 查找顺序:
    • NioServerSocketChannel → 没有实现
    • AbstractNioMessageChannel → 找到了!
  5. 所以调用的是 AbstractNioMessageChannel.newUnsafe()

步骤 9:NioMessageUnsafe 是什么

位置:io.netty.channel.nio.AbstractNioMessageChannel

public abstract class AbstractNioMessageChannel extends AbstractNioChannel {
    
    @Override
    protected AbstractNioUnsafe newUnsafe() {
        return new NioMessageUnsafe();
    }
    
    // NioMessageUnsafe 是 AbstractNioMessageChannel 的内部类
    private final class NioMessageUnsafe extends AbstractNioUnsafe {
        
        private final List<Object> readBuf = new ArrayList<Object>();
        
        @Override
        public void read() {
            assert eventLoop().inEventLoop();
            final ChannelConfig config = config();
            final ChannelPipeline pipeline = pipeline();
            final RecvByteBufAllocator.Handle allocHandle = unsafe().recvBufAllocHandle();
            allocHandle.reset(config);
            
            boolean closed = false;
            Throwable exception = null;
            try {
                try {
                    do {
                        // 【核心】调用 doReadMessages 接受新连接
                        int localRead = doReadMessages(readBuf);
                        if (localRead == 0) {
                            break;
                        }
                        if (localRead < 0) {
                            closed = true;
                            break;
                        }
                        allocHandle.incMessagesRead(localRead);
                    } while (allocHandle.continueReading());
                } catch (Throwable t) {
                    exception = t;
                }
                
                int size = readBuf.size();
                for (int i = 0; i < size; i++) {
                    readPending = false;
                    // 【核心】触发 channelRead 事件,传递新的 SocketChannel
                    pipeline.fireChannelRead(readBuf.get(i));
                }
                readBuf.clear();
                allocHandle.readComplete();
                pipeline.fireChannelReadComplete();
                
                // ... 异常处理和关闭逻辑
            } finally {
                // ...
            }
        }
    }
    
    // 由子类实现,用于接受新连接
    protected abstract int doReadMessages(List<Object> buf) throws Exception;
}

说明:

  • NioMessageUnsafe 是 AbstractNioMessageChannel 的内部类
  • read() 方法的核心功能:
    1. 调用 doReadMessages() 接受新连接
    2. 将新连接(NioSocketChannel)添加到 readBuf
    3. 触发 channelRead 事件,传递新连接

完整调用链路图

new NioServerSocketChannel()
    ↓
NioServerSocketChannel()
    ↓
NioServerSocketChannel(ServerSocketChannel)
    ↓
super(null, channel, OP_ACCEPT)
    ↓
AbstractNioMessageChannel(parent, ch, readInterestOp)
    ↓
super(parent, ch, readInterestOp)
    ↓
AbstractNioChannel(parent, ch, readInterestOp)
    ↓
super(parent)
    ↓
AbstractChannel(parent)
    ↓
unsafe = newUnsafe()  ← 在这里调用
    ↓
【多态机制】查找实际类型的 newUnsafe() 实现
    ↓
NioServerSocketChannel.newUnsafe()? → 没有
    ↓
AbstractNioMessageChannel.newUnsafe()? → 找到了!
    ↓
return new NioMessageUnsafe()
    ↓
unsafe 字段被赋值为 NioMessageUnsafe 实例

为什么是 NioMessageUnsafe?

设计原因:

NioServerSocketChannel 的工作是接受新连接,不是读取字节数据。

  • 每次 read() 操作返回的是一个对象(新的 NioSocketChannel)
  • 不是返回字节数据
  • 所以使用 NioMessageUnsafe(处理"消息/对象")

对比:

Channel 类型Unsafe 类型read() 方法作用
NioServerSocketChannelNioMessageUnsafe接受新连接,返回 NioSocketChannel 对象
NioSocketChannelNioByteUnsafe读取字节数据,返回 ByteBuf

总结

  1. unsafe 字段在哪里定义?

    • 在 AbstractChannel 中定义
  2. unsafe 字段在哪里初始化?

    • 在 AbstractChannel 构造方法中,通过调用 newUnsafe() 初始化
  3. 为什么调用的是 AbstractNioMessageChannel.newUnsafe()?

    • 因为 Java 多态机制
    • 虽然调用代码在 AbstractChannel 中
    • 但实际对象类型是 NioServerSocketChannel
    • JVM 从实际类型开始向上查找 newUnsafe() 的实现
    • 在 AbstractNioMessageChannel 中找到了实现
  4. unsafe 的实际类型是什么?

    • NioMessageUnsafe
  5. 为什么是这个类型?

    • 因为 NioServerSocketChannel 的工作是接受新连接(返回对象)
    • 不是读取字节数据
    • 所以使用 NioMessageUnsafe(处理消息/对象)

核心答案:服务端的 unsafe 是 NioMessageUnsafe 实例,由 Java 多态机制决定调用 AbstractNioMessageChannel.newUnsafe() 方法创建。

5分钟搞定!用ZLMediaKit搭建GB28181视频监控系统(含避坑指南) 本文提供了一份基于ZLMediaKit搭建GB28181视频监控系统的实战指南。文章详细介绍了从环境准备、核心组件(ZLMediaKit与SIP服务器)部署、摄像头配置到内外网穿透的完整流程,并重点分享了设备ID配置、防火墙设置等关键避坑经验,帮助开发者快速构建稳定可控的监控平台。 阅读详情

相关推荐

相机通用类之海康相机,软触发硬触发(飞拍),并输出halcon格式对象

如何显示图像:可以访问我文章开头的博客,通过编写相机通用类即可,程序中是有继承通用类,通过访问相机通用的获取图像数据,从而传输图像数据。具体可以查看相机通用类。整体过程其实比较简单,由于海康相机没有像一些品牌相机一样可以直接使用序列号开启相机,所以我们需要通过对相机信息进行索引,根据索引到的相机序列号来开启相机。

m0_51559565的博客 7621

Netty4.x 源码实战系列(三):NioServerSocketChannel全剖析

根据上一篇《Netty4.x 源码实战系列(二):服务端bind流程详解》所述,在进行服务端开发时,必须通过ServerBootstrap引导类的channel方法来指定channel类型, channel方法的调用其实就是实例化了一个用于生成此channel类型对象的工厂对象。 并且在bind调用后,会调用此工厂对象来生成一个新channel。本篇将通过NioServerSocketChannel

风清扬的专栏 2022

Vue项目实战:用DataV的dv-scroll-board打造高颜值滚动表格(附完整代码)

本文详细介绍了如何在Vue项目中使用DataV的dv-scroll-board组件打造高颜值滚动表格。从基础集成到高级配置,包括动态数据处理、深度样式定制、性能优化策略以及交互增强方案,帮助开发者快速实现企业级数据展示需求。特别针对样式优化和滚动表格的常见问题提供了实用解决方案。

weixin_30892037的博客 499

[netty核心类]--Channel和Unsafe类

主要内容: (1)Channel 功能说明 (2)Unsafe 功能说明 (3)Channel的主要实现子类源码分析 (4)Unsafe主要实现子类源码分析 1.Channel功能说明channel是netty网络IO操作抽象出来的一个接口,主要功能有:网络IO的读写,客户端发起连接、主动关闭连接,链路关闭,获取通信双方的网络地址等。下面分类进行介绍:网络IO操作 (1)C

惜暮 7170

通过两个mark点确定某一个点的位置

read_image (Image0, '0.bmp') binary_threshold (Image0, Region, 'max_separability', 'dark', UsedThreshold) connection (Region, ConnectedRegions) fill_up (ConnectedRegions, RegionFillUp) select_shape_std (RegionFillUp, SelectedRegions, 'max_area', 70) red...

优快云博客 3889

银河麒麟V11 + KVM/QEMU + GT 710 GPU直通 Win10 完整操作流程文档

宿主机:RTX 5080专门运行ollama大模型服务,通过SSH/VNC远程管理Win10虚拟机:GT 710直通,物理键盘专属,通过物理显示器处理视频应用硬件隔离:两个系统完全隔离,互不干扰,性能最大化两种不同的直通方式直通方式 配置方法 设备在宿主机的状态 典型应用场景PCIe设备直通 vfio-pci.ids=10de:128b,10de:0e0f 设备完全从宿主机消失,被vfio-pci驱动接管 GPU、网卡、NVMe硬盘。

weixin_45285654的博客 1154

NioServerSocketChannel的初始化源码

源码分析 上一节课我们就NioEventLoop的初始化进行了一个初步的讲解,他是Netty很重要的一个类,后面还有针对它的分析,大家先对我前面介绍的组件有一个初步的认识!仔细的看,看到后面会有一种豁然开朗的感觉! 我们这一节课学习服务端的ServerSocketChannel的初始化源码,首先,我们还是老规矩,我告诉你你从哪里找,他是如何一步一步调用到ServerSocketChannel的,然后在进行分析! 一、入口寻找 首先,我们大家再开发Netty服务端的时候,都会有这样几行代码: ServerBo

皇甫嗷嗷叫 342

MGC3130 3D手势识别传感器原理图设计,已量产(交互传感器)

最近在落地一款互动艺术装置的控制模块,选了 Microchip 的 MGC3130 做核心 —— 这颗芯片算是 GestIC® 近场传感技术的 “熟面孔” 了,把 3D 手势识别、运动跟踪的信号处理都集成在一颗芯片里,0-10cm 的检测距离刚好适配桌面级互动场景,挥挥手就能控设备的体验,放在艺术装置里确实很出效果。今天扒一下实际跑通的原理图,聊聊每个模块的设计思路。

不脱发的程序猿 371

Netty篇:NioServerSocketChannel启动注册流程源码分析

io.netty.channel.Channel是Netty网络操作抽象层,聚合了一组功能,包括但不限于网路的读写,客户端发起连接,主动关闭连接,链路关闭,获取通信双方的网络地址等。

走在路上 669

【人工智能】全面盘点国内AI九大模型:各擅胜场的智能先锋(豆包、文心一言、讯飞星火、通义千问、Kimi、智谱清言、腾讯元宝、秘塔、天工AI)

追求性价比与全能:选豆包,适合个人与中小企业日常使用;侧重中文创作与理解:选文心一言,文学与商业文案创作首选;需要专业语音交互:选讯飞星火,智能客服、车载场景必备;看重生态与多场景:选通义千问,适配电商、办公等企业需求;处理超长文本任务:选Kimi,文档分析、学术研究的利器;专注深度推理创作:选智谱清言,学术与创意写作的伙伴;依赖腾讯生态协同:选腾讯元宝,日常轻量需求的便捷之选;深耕法律学术领域:选秘塔,专业文本处理的权威工具;布局前沿技术体验:选天工AI,享受接近国际顶尖的智能服务。

奶爸的编程之路,也就一周冷个三天 1124

回归预测 | MATLAB实现TCN时间卷积神经网络多输入单输出回归预测

回归预测 | MATLAB实现TCN时间卷积神经网络多输入单输出回归预测

机器学习之心的博客,关注并私信文章链接,获取对应文章源码和数据。 2492

Netty源码分析之Channel

一、Channel实例化 在配置启动的时候,会传入channel参数,具体的参数值,根据客户自身需求自行传入(NIO、OIO还是Epoll)。在前一节中的initAndRegister方法中第一件事就是实例化channel。channel的实例化是通过ChannelFactory工厂通过反射调用实例化,本节分析取NioServerSocketChannel来分析整个实例化过程,看看Channel实例化过程需要做些什么工作。 NioServerSocketChannel的构造方法 Selector

solayang的博客 212

两万字硬核指南!Python爬虫requests库从入门到精通:新手也能搞定所有爬取场景(附实战案例+避坑大全)

请求头是客户端发送给服务器的额外信息,比如User-Agent(浏览器类型)、Referer(来源页面)、Cookie(登录凭证)、(编码方式)等。Cookie是服务器存储在客户端的小型文本文件,包含用户的登录凭证、偏好设置等信息。浏览器会在每次请求时自动携带Cookie,服务器通过Cookie识别用户身份。代理IP是一个中间服务器,你的请求先发送到代理IP,再由代理IP发送到目标网站,目标网站只能看到代理IP的地址,看不到你的真实IP。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1496

Netty源码分析:1.3初始化NioServerSocketChannel

第一章节是主要是服务器启动的代码分析。章节目录有: |———1.1初始化NioEventLoopGroup |———1.2初始化NioEventLoop |———1.3初始化NioServerSocketChannel |———1.4服务器启动流程 为什么先从初始化开始了解服务器启动? 因为在我看服务器启动的...

兜兜的博客 467

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Netty进阶:NioServerSocketChannel源码分析

1.准备ChannelFactory 2. 在哪实例化NioServerSocketChannel? 3. 构造函数链 4. newUnsafe(); 5. newChannelPipeline(); 小结 1.准备ChannelFactory Netty服务端的ServerBootstrap引导类的channel方法来指定channel类型,并且在bind...

TheLudlows的博客 1153

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Netty源码分析——服务端channle的创建(一)

首先我们看一下正常netty服务端启动的代码 public void server(int port) throws Exception { final ByteBuf buf = Unpooled.copiedBuffer("hello", Charset.forName("UTF-8")); EventLoopGroup bossGroup = new NioE...

cool_tone的博客 207

深度学习工具包 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之新连接接入源码分析

前言 分析之前,提出已下问题: 1.1 Netty是在哪里检测有新连接接入的? 1.2 新连接是怎样注册到NioEventLoop线程的? 本篇文章按照下图顺序进行分析 检测新连接 通过上述截图以及之前文章可知,netty通过selector#select获取IO就绪的SelectionKey 1.1 获取SelectionKey的事件:int readyOps = k.readyOps(); 1.2 如果readyOps为SelectionKey.OP_ACCEPT,则检测到新连接 获取Sel

snail-jie的博客 231

Netty服务端的启动源码分析

ServerBootstrap的构造: 1 public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerChannel> { 2 private static final InternalLogger logger = InternalLoggerFactory.getI...

weixin_30662109的博客 108

Netty源码分析之服务端启动流程

上节对Netty的做了简单介绍,这节分析下Netty启动流程,后面的源码分析都以Netty4.0.32版本为例,以下面启动代码为例子 public class TimeServer { public void bind(int port) throws Exception { //...

cherry93925的博客 194

Netty Channel源码分析

原文:https://wangwei.one/posts/netty-channel-source-analyse.html 前面,我们大致了解了Netty中的几个核心组件。今天我们就来先来介绍Netty的网络通信组件,用于执行网络I/O操作 —— Channel。 Netty版本:4....

chuqiong4119的博客 189

Netty源码分析-服务启动

EventLoopGroup bossGroup = new NioEventLoopGroup(); //配置 EventLoopGroup 线程组 EventLoopGroup workerGroup = new NioEventLoopGroup(); //配置 EventLoopGroup 线程组 try { ServerBootstrap b = new ServerBootstrap(); b.gr...

zhuyong7的博客 226

(二)Netty服务启动过程源码分析 — 初始化Channel

前言 上一篇分析了服务端启动类的源码,接下来我们在上一篇的代码的基础上,一步一步的看一下启动过程中是如何运作的。 由于启动过程代码调用链较长,所以分为两部分来分析。 本文分析的是启动过程中的初始化部分。 正文 io.netty.example.echo.EchoServer // 启动类中这一句是开始启动,我们跟进到bind方法中 ChannelFuture f = b.bind(PORT).sync(); io.netty.bootstrap.AbstractBootstrap

OrPis的专栏 267

Claude Desktop深度指南:Workspace原理与工程化落地

Claude Desktop并非本地大模型客户端,而是一款基于Electron构建、深度集成系统能力的AI协作工具。其核心技术支柱是Workspace——一种融合文件系统拓扑、语义分块与轻量向量索引的本地知识管理机制。它通过自动上下文注入、IDE联动和多工作区协同,显著提升工程师在代码理解、文档分析与跨项目验证等场景下的上下文粘性与操作效率。区别于通用AI聊天工具,Claude Desktop的价值聚焦于开发工作流缝合与本地敏感数据合规处理,尤其适用于需频繁切换技术栈、直连本地文件、保障数据不出域的前端/后

weixin_33937778的博客 354

源码分析与序列化

Netty源码分析 Netty中几个重要组件 AbstractBootStrap:启动辅助类 EventLoop:事件处理线程 ChannelHandler:处理器 AbstractChannel:通道 ChannelPipeline:管道 Unsafe:与Nio交互的媒介 ServerBootstrap

weixin_38910645的博客 134

Netty事件流程分析补充

pipeline责任链流程分析 责任链创建流程 入口程序 // 责任链的创建是在Channel的初始化的时候进行的 // AbstractChannel.java protected AbstractChannel(Channel parent) { // 如果当前为服务端的channel,则parent=null this.parent = parent; // 创建channe...

疾风先生的博客 950

Netty5服务端源码解析

Netty5源码解析 今天让我来总结下netty5的服务端代码。 服务端(ServerBootstrap) 示例代码如下: import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io...

weixin_34161064的博客 331
上一篇: Netty源码分析---NioEventLoop的run方法详解
下一篇: Netty源码分析---processSelectedKeys() vs runAllTasks()
不早睡不改名@
博客等级 码龄5年 536粉丝 306原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值