Java NIO之Selector详细理解

Java-NIO篇章(4)——Selector选择器详解 选择器的使命是完成IO的多路复用,其主要工作是通道的注册、监听、事件查询。一个通道代表一条连接通路,通过选择器可以同时监控多个通道的IO(输入输出)状况。选择器和通道的关系,是监控和被监控的关系。 选择器提供了独特的API方法,能够选出(select)所监控的通道已经发生了哪些IO事件,包括读写就绪的IO操作事件。 一般是一个单线程处理一个选择器,一个选择器可以监控很多通道。所以,通过选择器,一个单线程可以处理数百、数千、数万、甚至更多的通道。在极端情况下(数万个连接),只用一个线程就可以处理所有的通道。 阅读详情

介绍

       Selector一般称为选择器。它是Java NIO核心组件之一,选择器管理着一个被注册的通道集合的信息和它们的就绪状态。通道是和选择器一起被注册的,并且使用选择器来更新通道的就绪状态。

      

 

可选择通道(SelectableChannel)

抽象类SelectableChannel提供了实现通道的可选择性所需要的公共方法。继承该SelectableChannel的通道(如:socket通道)都是可选择的,因此可以配置成非阻塞模式。

 

//可以注册的Channel的抽象

public abstract class SelectableChannel

    extends AbstractInterruptibleChannel

    implements Channel

{
    //返回创建此通道的Provider
    public abstract SelectorProvider provider();


    //返回注册的SelectionKey(即事件的操作类型)
    public abstract int validOps();


    //判断当前Channel是否有注册到任意的Selector
    public abstract boolean isRegistered();


    //获取该Channel注册在Selector的SelectionKey(事件类型)
    public abstract SelectionKey keyFor(Selector sel);


     //将Channel注册到给定的Selector sel上,并指定注册的事件类型(SelectionKey.OP_READ,OP_WRITE,OP_CONNECT,OP_ACCEPT等)

    //attachment 为附属的resulting key,可以为null
    //只有非阻塞模型的Channel才能调用register方法
    public abstract SelectionKey register(Selector sel, int ops, Object att)


    //将Channel注册到给定的Selector sel上,并指定注册的事件类型(SelectionKey.OP_READ,OP_WRITE,OP_CONNECT,OP_ACCEPT等)
    public final SelectionKey register(Selector sel, int ops)


    //配置是否是阻塞模式
    public abstract SelectableChannel configureBlocking(boolean block)


    //获取当前是否是阻塞模式
    public abstract boolean isBlocking();


    //获取 configureBlocking和register方法同步的锁
    public abstract Object blockingLock();

}

 

选择键(SelectionKey)

选择键封装了特定的通道与特定的选择器的注册关系。选择键对象被SelectableChannel.register()返回并提供一个表示这种注册关系的标记。

SelectionKey常用的API如下

     

//选择键封装了特定的通道与特定的选择器的注册关系

public abstract class SelectionKey {

           //返回创建该Key的Channel对象,即使当前key被取消也会返回
           public abstract SelectableChannel channel();
  

           //返回创建该key的Selector
            public abstract Selector selector();
         

             //判断该key是否可用
             public abstract boolean isValid();


              //请求取消此键的通道向其选择器的注册。返回时,该密钥将无效,并将被添加到其选择器的已取消密钥集中。在下一次选择操作期间,该键将从所有选择器的键集中删除。
           public abstract void cancel();


           //  获取此键的 interest 集合。
           public abstract int interestOps();


           //将此键的 interest 集合设置为给定值。
           public abstract SelectionKey interestOps(int ops);


           //获取该通道已经就绪的操作
           public abstract int readyOps();


           public static final int OP_READ = 1 << 0;  //读操作事件
           public static final int OP_WRITE = 1 << 2;  //写操作事件
           public static final int OP_CONNECT = 1 << 3;  //连接事件
           public static final int OP_ACCEPT = 1 << 4;  //接受事件


           //测试此键的通道是否已准备好进行读取。
            public final boolean isReadable()


           //测试此键的通道是否已准备好进行写入。
           public final boolean isWritable()


           // 测试此键的通道是否已完成其套接字连接操作。
           public final boolean isConnectable()


            // 测试此键的通道是否已准备好接受新的套接字连接。
             public final boolean isAcceptable()


           //将附加对象绑定到SelectionKey上,便于识别给定的通道
           public final Object attach(Object ob)


            //取出绑定在SelectionKey上的附加对象
             public final Object attachment()
}

 

       jdk1.8版本SelectionKey有4中事件,OP_READ(读事件)、OP_WRITE(写事件)、OP_CONNECT(连接事件)和OP_ACCEPT(接受事件)。

      

Selector选择器

              Selector常用的API    

 public abstract class Selector implements Closeable {

    //创建一个选择器
    public static Selector open()


    //获取当前选择器是否已打开
    public abstract boolean isOpen()


    //返回创建此通道的提供者
    public abstract SelectorProvider provider()


   //返回此选择器的键集
    public abstract Set<SelectionKey> keys()


   //返回此选择器已选择的键
    public abstract Set<SelectionKey> selectedKeys()


   //获取已经I/O准备就绪的键集,不会阻塞
    public abstract int selectNow()


    //阻塞直到注册到Selector上的Channel有事件发生,或者到了超时时间
    //指定最长等待阻塞的时间,单位ms

    public abstract int select(long timeout)



    //阻塞直到注册在Selector中的Channel 发送可读写事件(或其他注册事件)
    public abstract int select()

    //唤醒调用select()阻塞的线程
    public abstract Selector wakeup()


    //关闭Selector
    public abstract void close()

}

 

open方法

open()方法用于创建一个Selector对象

Selector selector = Selector.open();

 

将Channel注册到Selector中

我们需要将 Channel 注册到Selector 中,这样才能通过 Selector 监控 Channel 中的事件,注:一个Channel要注册到Selector中,需要先将这个Channel设置成非阻塞模式。

//设置成非阻塞模式

channel.configureBlocking(false);

SelectionKey key = channel.register(selector, SelectionKey.OP_READ);

select方法

       select()和select(long timeout),select方法是Selector的核心方法,这两个方法会阻塞线程。

       select(long timeout):阻塞直到注册到Selector上的Channel有事件发生,或者到了超时时间指定最长等待阻塞的时间,单位ms

       select():阻塞直到注册在Selector中的Channel 发送可读写事件(或其他注册事件)

除了正常收到事件或超时还有三种方法可以唤醒在select()中阻塞的线程

        1. wakeup()

         2. close()

         3. interrupt()

 

获取就绪的Channel

Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();


while(keyIterator.hasNext()) {
    SelectionKey key = keyIterator.next();
    keyIterator.remove();


    //可能有多个注册事件就绪
    if(key.isAcceptable()) {
        // a connection was accepted by a ServerSocketChannel.
    }


    if (key.isConnectable()) {
        // a connection was established with a remote server.
    }



    if (key.isReadable()) {
        // a channel is ready for reading
    }


    if (key.isWritable()) {
        // a channel is ready for writing
    }

}

注意, 在每次迭代时, 我们都调用 “keyIterator.remove()” 将这个 key 从迭代器中删除, 因为 select() 方法仅仅是简单地将就绪的 IO 操作放到 selectedKeys 集合中, 因此如果我们从 selectedKeys 获取到一个 key, 但是没有将它删除, 那么下一次 select 时, 这个 key 所对应的 IO 事件还在 selectedKeys 中.

 

 

attach 和 attachment 方法

 public final Object attach(Object ob)  将附加对象绑定到SelectionKey上,便于识别给定的通道

             public final Object attachment()  取出绑定在SelectionKey上的附加对象

 

ServerSocketChannel和Selector使用示例:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;



public class SelectSocketsThreadPool {
    private static final int MAX_THREADS = 5;  //线程池数量
    public static int PORT_NUMBER = 7786;  //指定默认端口号
    private ThreadPool  pool = new ThreadPool(MAX_THREADS);



    public static void main(String[] args) throws Exception {
            new SelectSocketsThreadPool().go(args);
    }



    public void go(String [] args) throws Exception {
        int port = PORT_NUMBER;
        if (args.length > 0){
            port = Integer.parseInt(args[0]);
        }
        System.out.println("Listening on port "+port);



        //初始化ServerSocketChannel
        ServerSocketChannel serverChannel = ServerSocketChannel.open();

        //该ServerSocketChannel对应的ServerSocket
        ServerSocket serverSocket = serverChannel.socket();

        //初始化一个Selector
        Selector selector = Selector.open();


        serverSocket.bind(new InetSocketAddress(port));  //绑定端口
        serverChannel.configureBlocking(false);  //非阻塞



        //绑定 ACCEPT事件
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);


        while (true){
            //阻塞直到有新的连接
            int n= selector.select();
            if (n == 0){
                continue;
            }

            Iterator it = selector.selectedKeys().iterator();

            while (it.hasNext()){
                SelectionKey key = (SelectionKey)it.next();
                if (key.isAcceptable()) { //key是ACCEPT
                    System.out.println("accept connection!");

                    //获取该key对应的Channel
                    System.out.println();
                    ServerSocketChannel server = (ServerSocketChannel)key.channel();

                    //接收到的SocketChannel
                    SocketChannel channel = server.accept();
                    registerChannel(selector,channel,SelectionKey.OP_READ);
                    sayHello(channel);
                }



                if (key.isReadable()){
                    readDataFromSocket(key);
                }


                it.remove();
            }
        }
    }



    private void sayHello(SocketChannel channel) throws IOException {
        buffer.clear();
        buffer.put("Hi there!\r\n".getBytes());
        buffer.flip();
        channel.write(buffer);
    }





    private ByteBuffer buffer = ByteBuffer.allocateDirect(1024);



    //连接上来的SocketChannel,注册到当前Selector上,注册的操作为READ
    protected void registerChannel(Selector selector, SocketChannel channel, int opRead) throws IOException {
        if (channel == null){
           return;
        }


        channel.configureBlocking(false);
        channel.register(selector,opRead);
    }





    //读取数据
    protected void readDataFromSocket(SelectionKey  key) {
        WorkThread workThread = pool.getWorker();
        if (workThread == null){
            return;
        }


        workThread.serviceChannel(key);
    }







    class ThreadPool {
        List idle = new LinkedList();
        //创建指定数量的线程并添加到空闲队列idle中
        ThreadPool(int poolSize) {
            for (int i = 0 ; i < poolSize; i++){
                WorkThread  thread = new WorkThread(this);
                thread.setName("Worker" + (i+1));
                thread.start();
                idle.add(thread);
           }
        }





        //从队列中获取空闲线程
        WorkThread getWorker(){
            WorkThread workThread = null;
            synchronized (idle){
                if (idle.size() > 0){
                    workThread = (WorkThread)idle.remove(0);
                }
            }
            return workThread;
        }



        //将线程返还到空闲线程
        void returnWorker(WorkThread workThread){
            synchronized (idle){
                idle.add(workThread);
            }
        }
    }





    //线程执行的任务类

    class WorkThread extends Thread {
        private ByteBuffer  buffer = ByteBuffer.allocate(1024);
        private ThreadPool pool;
        private SelectionKey key;


        WorkThread(ThreadPool pool){
            this.pool = pool;
        }


        @Override
        public synchronized void run() {
            System.out.println(this.getName() +" is ready");
            while (true){
                try{
                   this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }


                if (key == null){
                   continue;
                }


                System.out.println(this.getName() +" has been awakened");
                try{
                    drainChannel(key);  //处理就绪的key
                }catch (Exception e){
                    System.out.println(" caught "+ e + "closing channel");

                    try {
                        key.channel().close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }


                key = null;
                this.pool.returnWorker(this);  //线程处理完任务放回空闲队列
            }
        }



        synchronized void serviceChannel(SelectionKey key){
            this.key = key;
            key.interestOps(key.interestOps() & (~SelectionKey.OP_READ));
            this.notify();
        }



        //处理就绪的key
        private void drainChannel(SelectionKey key) throws IOException {
            SocketChannel channel = (SocketChannel)key.channel();
            int count;
            buffer.clear();
            while ((count = channel.read(buffer)) > 0 ){
                System.out.println(new String(buffer.array(),0,count));
                buffer.flip();
                while (buffer.hasRemaining()){
                    channel.write(buffer);
                }

                buffer.clear();
            }


            if (count < 0){
                channel.close();
                return;
            }


            key.interestOps(key.interestOps() | SelectionKey.OP_READ);
            key.selector().wakeup();
        }



        private String decode(ByteBuffer bb) {
            Charset charset = Charset.forName("ASCII");
            return charset.decode(bb).toString();
        }

    }

}

 

感谢:

《Java NIO》

https://blog.youkuaiyun.com/u014634338/article/details/82865622

http://tutorials.jenkov.com/java-nio/selectors.html

 

 

深深的码丨Java NIO 透析 Java 中传统的 IO 包基于流模型实现,交互方式为同步、阻塞,当发生读取或写入操作时,线程会阻塞在此,直到操作完成。编码时采用这种方式虽然源码较直观易维护,但容易产生应用性能下降问题,且 IO 效率及其拓展性存在较大局限 Java 1.4 开始引入 NIO 框架,提供了 Channel(通道)、Selector(IO复用器/选择器)、Buffer(缓冲区),可构建多路复用、同步非阻塞的 IO... 阅读详情

相关推荐

Java NIO源码解析:深入理解Selector机制

Java NIO(New Input/Output)是Java提供的一种新的I/O操作方式,自从Java 1.4版本引入以来,它为开发者提供了更加灵活和高效的网络编程方式。NIO在设计上与传统的Java I/O API有很大的不同,特别是在支持非阻塞I/O操作方面。与基于流的阻塞I/O模型相比,Java NIO使我们能够使用较少的线程处理更多的网络连接,从而显著提高了I/O操作的效率。

weixin_42465140的博客 356

Selector的使用

这里没有在 Scrapy 框架中运行,而是把 Scrapy中的Selector 单独拿出来使用了,构建的时候传入text 参数,就生成了一个Selector选择器对象,然后就可以像Scrapy中的解析方式一样,调用xpath、css等方法来提取数据了。由于Selector 主要是与Scrapy结合使用,如 Scrapy的回调函数中的参数response 直接调用 xpath或者 css 方法来提取数据,所以在这里我们借助 Scrapy shell 来模拟Scrapy 请求的过程,讲解相关的提取方法。

W_chuanqi的博客 3405

nsight-system教程

参考nsight-compute使用教程-优快云博客。

youzjuer的博客 1894

Java语言进阶:Selector(选择器)

Java语言进阶:Selector(选择器) Selector(选择器) 多路复用的概念 选择器Selector是NIO中的重要技术之一。它与SelectableChannel联合使用实现了非阻塞的多路复用。使用它可以节省CPU资源,提高程序的运行效率。 "多路"是指:服务器端同时监听多个“端口”的情况。每个端口都要监听多个客户端的连接。 服务器端的非多路复用效果 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LdX0nfgv-1653801397411)(img/11

weixin_48351326的博客 4965

关于RT-Thread中PWM无法正常输出的学习

按照官方的PWM配置,并没有输出PWM,网上有比较多的办法,试了很多,有些还是不能实现输出,这里做个记录。记录自己完成PWM输出的过程,以及修改的地方。 关于STM32CubeMX配置就不多说了,网上有很多。 首先必定是按照流程来,一定一定按照流程来!!! 需要注意的是加上通道数!!!! 这是流程上没有的,也是RTT的一点小BUG吧 配上board.c中添加的代码,我用的是PA2定时2的通道3,需要使用的朋友修改对应定时器和GPIO! void HAL_TIM_Base_MspInit(TIM_Han

weixin_42566346的博客 3557

Cloudflare 5秒盾逆向实战:13次请求背后的Python补环境框架搭建指南

本文深入解析了如何通过Python构建浏览器环境模拟框架,以应对Cloudflare 5秒盾等现代Web防护机制。文章详细拆解了其背后复杂的13次请求链,涵盖了JavaScript执行引擎集成、DOM事件模拟、网络请求控制及Canvas指纹等环境检测的完整实现方案,为自动化数据采集和逆向工程提供了实战指南。

gold的博客 356

NIO-Selector类详解

Selector本身为抽象类,AbstractSelector是Selector类的抽象实现类,具体的实现类更加底层(SelectorImpl,位于sun.nio.ch);Selector即为"选择器",支撑了NIO的多路复用.Selector不能直接创建,需要通过Selector.open()获得,该方法将使用系统默认的选择器提供者创建新的选择器(SelectorProvider),可以通过...

深入一点 774

E-SMILES:化学信息学中的分子表示革命与应用

分子表示是化学信息学和计算化学的基础技术,其核心是将复杂的分子结构转化为计算机可处理的数字化形式。传统SMILES格式虽然广泛应用,但在处理复杂化学体系时存在局限性。Extended SMILES(E-SMILES)通过扩展语法规则,支持立体化学、配位键等特殊结构的精确描述,显著提升了分子表示的准确性和适用范围。在药物研发中,E-SMILES能准确描述蛋白质-配体相互作用和共价抑制剂;在材料科学领域,它支持纳米材料和超分子体系的多尺度建模。结合机器学习等前沿技术,E-SMILES正在推动化学信息处理效率的革

weixin_28683165的博客 282

8.JAVA NIO核心之选择器(Selector)

highlight: arduino-light 选择器(Selector)概述 选择器Selector是 SelectableChannle 对象的多路复用器,Selector 可以同时监控多个SelectableChannel的 IO 状况,也就是说,利用 Selector可使一个单独的线程管理多个 Channel。Selector 是非阻塞 IO 的核心 Java 的 NIO...

qq_30635523的博客 491

MicroCap声学仿真介绍(三)-人耳的频率响应

这里需要注意的是,24mm我们会填为”24m”,这里的“m”是毫的意思,24m意思是24e-3,同理7.4mm我们可以填为7.4m,意思是7.4e-3。MicroCap声学库中,已内置“声源”模块和“管”模块,我们需要调用这两个模块,并用连接线将这两个模块连接到一起,完成仿真工作。上图中第一个图是在管的一端输入1Pa(94dBSPL)的信号,管的另一端的不同频率的声压大小的仿真结果。上述的结果跟我们的常识也是符合的。换言之,我们要仿真的目的是在管的一端加1pa的声压时,管的另一端不同频率下的声压分布。

山无忧的博客 1474

第一节:从Chat_Bot 到 AI_Agent——一个范式转换

本文系统剖析了工业级AI代理系统ClaudeCode的设计原理与工程实践。通过对比ChatBot与Agent的三个本质差异:自主循环决策vs单轮应答、环境交互vs纯文本I/O、持久状态管理vs无状态对话,揭示了构建生产级Agent系统的关键挑战。文章详细解析了ClaudeCode的五层架构设计、1800+文件组成的运行时系统,包括工具调度、权限管理、状态持久化等核心机制,并阐述了从简单API调用到完整Agent系统的演进路径。

2201_75869398的博客 69

Java NIO理解(四)Selector

  前面介绍过Channel、Buffer,后面的文章主要讲解Selector的实践以及实现原理,选择器的概念比起通道、缓冲区要复杂一些,并且选择器是NIO中最重要的一部分内容。 为什么使用Selector   Selector又称为“选择器”,单个线程通过Selector可以管理多个SelectableChannel,实际应用中管理多个请求连接。对于操作系统来说,线程之间上下文切换的开销很大,而...

热心网友 269

人工智能训练师三级考试大纲深度解读|理论+实操分值分布+六大模块占比

三级人工智能训练师考试分为理论和实操两大模块(各100分,合格线60分)。理论考试包含AI基础(30%)、数据标注(25%)、模型训练(20%)、测试(15%)和系统运维(10%),题型为客观题;实操考核侧重数据标注(40%)、模型测试(35%)和系统运维(25%),采用现场操作形式。复习应优先关注AI基础和数据标注等高分值模块,实操需重点掌握标准流程和结果准确性(占评分70%)。考试要求两模块均达标,理论侧重概念理解,实操强调规范执行与文档完整。

白话机器学习 1106

java NIO selector全面深入理解

java NIO selector全面深入理解

lw305080的博客 1万+

2023年下半年网络工程师案例分析真题答案解析

R1] ip route-static 0.0.0.0 0.0.0.0 GigabitEthemet2/0/1 (3) track (4) R1 to R2 //配置R1的缺省路由,联动BFD使得R1到2的流量优先走R1->S1->R2链路,当此链路发生故障时,流量切换到R1->R3->R2链路上。当同一VLAN内也需要网络隔离时,我们可采用交换机的(2)功能,若在配置了二层隔离后,部分主机有互通的需求,则可在需求主机的网关上配置(3)功能。不需要,MAC地址是数据链路层封装以太帧的地址标识。

鹿鸣天涯 752

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

java 同步非阻塞的nio中包含阻塞的selector的理解

nio与selector的联系: NIO自从JDK1.4版本以来就添加的一个非阻塞I/O框架,NIO是Java为解决网络通讯中高并发问题的一个类库,Selector是java NIO的一个组件,用于检查一个或多个NIO Channel的状态是否处于可读、可写。如此可以实现单线程管理多个channels,也就是可以管理多个网络链接,所以Selecotr是实现了多路复用的关键。 纠结点: java n...

SuperBins的博客 1267

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Java NIO 三大核心(Buffer、Channel、Selector)理解

NIO 三大核心(Buffer、Channel、Selector)

在路上 1098

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

java 异步io selector_JAVA NIO是同步非阻塞I/O的理解与NIO多路复用器Selector

本文链接:https://blog.youkuaiyun.com/qq_36118769/article/details/85293865一般来说,服务器端的I/O主要有两种情况:一是来自网络的I/O;二是对文件(设备)的I/O。首先一个IO操作其实分成了两个步骤:发起IO请求和实际的IO操作,同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO,因此阻塞IO、非...

weixin_39587822的博客 281

JAVA NIO是同步非阻塞I/O的理解与NIO多路复用器Selector

一般来说,服务器端的I/O主要有两种情况: 一是来自网络的I/O; 二是对文件(设备)的I/O。 首先一个IO操作其实分成了两个步骤:发起IO请求和实际的IO操作,同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO,因此阻塞IO、非阻塞IO、IO复用、信号驱动IO都是同步IO,如果不阻塞,而是操作系统帮你做完IO操作再将结果返回给你,那么就是异步IO。 阻塞IO和非阻塞IO的区别在于第一步,发起IO请求是否会被阻塞,如果阻塞直到完成那么就是传统的阻塞IO

颜的博客 1346

java nio 多路复用_BIO到NIO源码的一些事儿之NIO 下 之 Selector

前言此系列文章会详细解读NIO的功能逐步丰满的路程,为Reactor-Netty 库的讲解铺平道路。 关于Java编程方法论-Reactor与Webflux的视频分享,已经完成了Rxjava 与 Reactor,b站地址如下:Rxjava源码解读与分享:https://www.bilibili.com/video/av34537840Reactor源码解读与分享:https://www.bilib...

weixin_39552538的博客 340

Java NIO编程实例之三Selector

Java NIO主要包含三个概念,即缓冲区(Buffer)、通道(Channel)和选择器(Selector)。前面的文章已经介绍了缓冲区和通道,本文则讲述最复杂的选择器Selector。 本文是本系列的第三篇文章,关于缓冲区Buffer可以看第一篇: https://zhuanlan.zhihu.com/p/25701512 关于通道Channel可以看第二篇: https://zhuan

LogicTeamLeader的专栏 2594

NIO的简单理解

在之前的IO内存模型梳理的时候,也提到过NIO: I/O(input/output)内存模型(2)_PigeonEssence的博客-优快云博客我们了解了I/O的基本概念,之后需要讨论的就是比如Java支持三大I/O模型,BIO,NIO和AIO1.BIOBIO就是Blocking I/O, 同步阻塞型IO,数据的读取写入必须阻塞在一个线程内等待其完成。我们很熟悉的java输入和输出流都是基于BIO去实现的,如InputStream,OutputStream等。 (这种Block是不会影响同时运行的其他程

PigeonEssence的博客 1万+

java selector 源码_13. 《Java源码解析》之NIO的Selector机制(Part1:Selector.open())

Selector机制之Selector.open()函数的解析在NIO中我们一般都是Channel与Selector配合使用的,一般情况下使用的方法如下://打开Selector来处理channelSelector selector = Selector.open();//将channel注册到selector中,并将channel设置成等待新的连接serverChannel.register(s...

weixin_36399948的博客 460

2.Java NIO之Selector使用方法简介

前言 在之前文章1. Java NIO三大部件概述中简单提及Selector概念、优缺点以及Netty中对其的优化,在这篇文章将对Selector的使用方法进行简单介绍。 1. Selector创建 Selector selector = Selector.open(); 2. 注册Channel到Selector Selector要能够管理Channel,需要将Channel注册到Select...

weixin_43257196 的博客 760

【Java.NIO】Selector,及SelectionKey

java.nio.channels public abstract class Selector extends Object implements Closeable Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接。 使用Select

王晓斌的专栏 2万+
上一篇: Java NIO之Channel详细理解
下一篇: Scalable IO in Java
思维的深度
博客等级 码龄11年 2万+粉丝 391原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值