资讯专栏INFORMATION COLUMN

如何理解I/O多路复用

desdik / 1927人阅读

摘要:为了讲清复用的是什么,首先得先说明一下逻辑流的概念。理解了这个,那么所谓的复用,指的就是在一个逻辑流里处理多个事件如何做到利用多路复用器,轮询监听各路,如果一旦有事件发生,那么就去处理,否则程序阻塞。

java nio提供了一套称为I/O多路复用的编程范式,那么什么叫做I/O多路复用呢?
所谓的I/O多路复用,从字面意思上来理解,就是:
有多个I/O操作(或是写,或是读,或是请求),这多个I/O操作都共用一个逻辑流
为了讲清复用的是什么,首先得先说明一下逻辑流的概念。
逻辑流是什么?这里的逻辑流和操作系统中"线程是进程的一个逻辑流"是一个意思。
下面的就是一个逻辑流:

{
int a = 5;
int b a*a;
double c = a/b;
}

下面又是一个逻辑流:

{
long b = 5;
int c = b+3;
}

如果在一个进程中,如果没有线程,那么程序是顺序执行的,那么所有的代码都是属于一个逻辑流。
比如说,上面的两端代码,如果合在一个进程当中,它们一定是这种结构:

{
int a = 5;
int b a*a;
double c = a/b;
}
....
{
long b = 5;
int c = b+3;
}

或是

{
long b = 5;
int c = b+3;
}
....
{
int a = 5;
int b a*a;
double c = a/b;
}

也就是说它们一定属于一个逻辑流(一个顺序结构)。
理解了这个,那么所谓的I/O复用,指的就是在一个逻辑流里处理多个I/O事件!!!
如何做到?利用Selector多路复用器,轮询监听各路I/O,如果一旦有I/O事件发生,那么就去处理,否则程序阻塞。
来看一个程序,加深理解:

package qiuqi.filedownloadtest;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.*;
import java.util.Iterator;

public class FileServer {


    public static void main(String[] args) throws IOException {


        startServer();
    }

    public static void startServer() throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(9999));
        serverSocketChannel.configureBlocking(false);
        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        while (selector.select() > 0)
        {
            Iterator iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext())
            {
                SelectionKey key = iterator.next();
                iterator.remove();
                if(key.isAcceptable())
                {
                 System.out.println("收到连接这个I/O事件");
                 catch (IOException e){e.printStackTrace();}

                }
            }
        }

    }
}

这是一个监听网络I/O的多路复用程序,java中只能监听网络I/O,不能监听标准输入输出等I/O(不过这些在linux里都可以)。
我们发现,这个程序的原理就是开启一个网络I/O类,ServerSocketChannel,把它注册到Selector(选择器)上,然后选择器就开始
轮询,直到发现一个I/O事件,于是就进入第一个while循环进行处理,否则一直阻塞在select()>0处。
这是一个极其简陋的程序,但是它揭示了多路复用的真正内涵,也就是用一个逻辑流监听,处理多个I/O(不过处理程序其实可以开启多线程,也就是指第一个while循环里的部分)。
这就是I/O多路复用!!!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73557.html

相关文章

  • JAVA NIO 一步步构建I/O多路复用的请求模型

    摘要:为解决这问题,我们发现元凶处在一线程一请求上,如果一个线程能同时处理多个请求,那么在高并发下性能上会大大改善。这样一个线程可以同时发起多个调用,并且不需要同步等待数据就绪。表示当前就绪的事件类型。 JAVA NIO 一步步构建I/O多路复用的请求模型 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.com/jasonGeng88/blog 文章一:JAVA ...

    X_AirDu 评论0 收藏0
  • 《Node.js设计模式》欢迎来到Node.js平台

    摘要:事件多路复用器收集资源的事件并且把这些事件放入队列中,直到事件被处理时都是阻塞状态。最后,处理事件多路复用器返回的每个事件,此时,与系统资源相关联的事件将被读并且在整个操作中都是非阻塞的。 本系列文章为《Node.js Design Patterns Second Edition》的原文翻译和读书笔记,在GitHub连载更新,同步翻译版链接。 欢迎关注我的专栏,之后的博文将在专栏同步:...

    Paul_King 评论0 收藏0
  • Java IO初探

    Java IO对大多数Java程序员来说是熟悉又陌生,熟悉的是感觉到处都有它的身影,小到简单的读取文件,大到各种服务器的应用,陌生的是Java IO背后到底是一个怎样的机制,今天就让我们去了解一下这位老朋友吧。本文不讲解Java IO如何具体使用,有这方面需求的同学可以自己查下。 IO模型 要说IO,就不得不说IO模型,IO模型大家都有所了解,同步异步,阻塞非阻塞什么的,总的来说IO模型可分为以下...

    edgardeng 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<