zoukankan      html  css  js  c++  java
  • Java IO/NIO

    阻塞IO模型

    最传统的IO模型,读写数据过程中会发生阻塞现象,当用户线程发出IO请求之后,内核会去查看数据是否就绪,若没有就绪就会等待数据就绪,用户线程处于阻塞状态,用户线程交出CPU,当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程解除block状态

    • 典型的例子:data = socket.read(),如果没有数据,就会阻塞在read方法

    非阻塞IO模型

    当用户线程发起一个read操作后,不需要等待,马上就得到一个结果,若结果是一个error,直到数据没有准备好,再次发送read操作

    一旦内核中数据准备好了,并且再次收到了用户线程的请求,马上将数据拷贝到用户线程,然后返回

    在非阻塞IO模型中,用户线程需要不断询问内核数据是否就绪,非阻塞IO不会交出CPU,一直占用CPU

    while(true){
        data = socket.read();
        if(data != error){
            // 处理数据
            break;
        }
    }

    在while循环中需要不断地去询问内核数据是否就绪,这样会导致CPU占用率非常高,很少用while循环读取数据

    多路复用IO模型

    JavaNIO实际上就是多路复用IO,多路复用IO中,会有一个线程不断去轮询多个socket状态,只有当socket真正有读写事件时,才真正调用实际地IO读写操作

    JavaNIO中,通过selector.select()去查询每个通道是否有到达事件,如果没有事件,则一直阻塞在那里,这种方式会导致用户线程的阻塞

    多路复用IO,通过一个线程,可以管理多个socket,只有当socket真正有读写事件发生才会占用资源进行实际的读写操作,多路复用IO比较适合连接数较多的情况

    多路复用IO为何比非阻塞IO模型的效率高是因为在非阻塞IO中,不断地询问socket状态时通过用户线程去进行地,在多路复用IO中,轮询每个socket状态是在内核进行的,这个效率比用户线程高得多

    信号驱动IO模型

    在信号驱动IO模型中,当用户线程发起一个IO请求操作,会给对应得socket注册一个信号函数,然后用户线程会继续执行,当内核数据就绪时发送一个信号给用户线程,用户线程接收到信号之后,便在信号函数中调用IO读写操作来进行实际的IO请求操作

    异步IO模型

    异步IO模型是最理想的IO模型,在异步IO模型中,当用户线程发起read操作之后,立刻就可以开始去做其他的事,从内核角度,当它受到一个asynchronous read后,它会立刻返回,说明read请求成功了

    不会对用户线程产生任何block,内核会等待数据准备完成,然后将数据拷贝到用户线程,当这一切都完成之后,内核会给用户线程发送一个信号,告诉它read完成

    用户线程完全不需要实际的IO操作是如何进行的,只需要发起一个请求,当接收内核返回的成功信号时表示IO操作已经完成,可以直接使用数据

    在异步模型中,IO操作两个截断不会阻塞用户线程,两个阶段都是由内核自动完成,发送一个信号告知用户线程操作完成,用户线程不需要再次调用IO函数进行读写

    • 信号驱动模型中,当用户线程接收到信号表示数据已经就绪,然后用户线程调用IO函数进行读写操作
    • 异步IO模型中,受到信号表示IO操作已经完成,不需要在用户线程中调用IO函数进行实际的读写操作

    Java NIO

    论读书
    睁开眼,书在面前
    闭上眼,书在心里
  • 相关阅读:
    POJ 1953 World Cup Noise
    POJ 1995 Raising Modulo Numbers (快速幂取余)
    poj 1256 Anagram
    POJ 1218 THE DRUNK JAILER
    POJ 1316 Self Numbers
    POJ 1663 Number Steps
    POJ 1664 放苹果
    如何查看DIV被设置什么CSS样式
    独行DIV自适应宽度布局CSS实例与扩大应用范围
    python 从入门到精通教程一:[1]Hello,world!
  • 原文地址:https://www.cnblogs.com/YC-L/p/13755346.html
Copyright © 2011-2022 走看看