BIO、NIO、AIO入门认识

同步、异步。阻塞。非阻塞概念理解

同步:

  • 比如在执行某个逻辑业务,在没有得到结果之前一直处于等待阻塞状态,得到结果后才继续执行

异步:

  • 比如在执行某个逻辑业务,在没有得到结果可以去干其他的事情,等待通知再回来执行刚才没执行完的操作。

阻塞:

  • 比如在执行某个逻辑业务,在结果没有返回之前,当前线程会被挂起,直到有结果了才继续执行

非阻塞:

  • 非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程的执行,继续执行直接返回    

IO、BIO、NIO、AIO

  • Java BIO : 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
  • Java NIO : 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
  • Java AIO(NIO.2) : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。

IO : 

  IO操作分为两个部分:发起IO请求、IO数据读写,再简单一点就input和output流,作用于数据传 

BIO : 阻塞IO

  最广泛的模型是阻塞I/O模型,默认情况下,整个过程是阻塞的,直到数据复制到进程缓冲区时才返回

 

NIO : 同步非阻塞IO

 

 NIO的三个组成部分: Channel(通道)、Buffer(缓冲区)、Selecter(选择器)

  Channel  :通道

   Channel是一个对象,连接Date数据和缓冲区的桥梁,看以看成IO中的流,不同的是: 

    • 流分为读取流和写入流是单向的,通道是双向的,既可以读又可以写;

    • hannel可以进行异步的读写;

    • Channel是通过Buffer来读写数据的,Buffer才是处理数据的对象,Channel只是桥梁

    • 因为Channel是双向的,所以Channel可以比流更好地反映出底层操作系统的真实情况

  Buffer   :缓冲区

   Buffer是一个缓冲区对象,数据是从通道读入缓冲区,从缓冲区写入到通道中的

    从Buffer读写数据一般遵循以下四个步骤

     写入数据到 Buffer;

     调用 flip() 方法;

     从 Buffer 中读取数据;

     调用 clear() 方法或者 compact() 方法。

  • 当向 Buffer 写入数据时,Buffer 会记录下写了多少数据。

  • 一旦要读取数据,需要通过 flip() 方法将 Buffer 从写模式切换到读模式。

  • 在读模式下,可以读取之前写入到 Buffer 的所有数据。

  • 一旦读完了所有的数据,就需要清空缓冲区,让它可以再次被写入。

  • 有两种方式能清空缓冲区:调用 clear() 或 compact() 方法。

  • clear() 方法会清空整个缓冲区。compact() 方法只会清除已经读过的数据。

  • 任何未读的数据都被移到缓冲区的起始处,新写入的数据将放到缓冲区未读数据的后面。

  •     public void test1(String r,String w) throws IOException {
            //声明读取文件和写入文件
            FileInputStream fi=new FileInputStream(new File(r));
            FileOutputStream fo=new FileOutputStream(new File(w));
            //获得传输通道channel
            FileChannel inChannel=fi.getChannel();
            FileChannel outChannel=fo.getChannel();
          //获得容器buffer
            ByteBuffer buffer= ByteBuffer.allocate(1024);
            while(true){
                //判断是否读完文件
                int eof =inChannel.read(buffer);
                if(eof==-1) {
                    break;
                }      
            //从读取模式转换我写入模式
            buffer.flip();
            //开始写
            outChannel.write(buffer);
            //写完要清空重置buffer缓冲区,
            buffer.clear();
            }
            inChannel.close();
            outChannel.close();
            fi.close();
            fo.close();
        }   
    }

Selector :选择器

 Selecter是一个选择器对象,它可以注册到各个Channel上并监听发生的事件,

  优点:1.通过一个线程管理多个Channel,就可以处理大量网络连接了。

     2.线程上下文的切换在高并发是的开销很大,使用Selecter,对许系统动用的线程来说,是优化的

  由于selector的原因,可以将NIO简单区分为两种:普通的NIO,和多路复用的NIO(加入了selector管理)

   普通的NIO :         

    •  NIO在IO操作的准备数据阶段时有一个轮询操作,

    •  会不停地发出“system call”到kernel轮询数据是否准备好,

    •  没准备好,应用进程可以处理其他事,

    •  准备好了之后在发出一个“system call”到kernel进行第二个阶段复制数据,

    •  这个过程是blocking的,所以NIO的特点就是在IO执行的第一阶段不会阻塞,

    •  但是在第二阶段将数据从内核拷贝到进程这个真是的IO操作还是会阻塞。

 

   路复用NIO:        

    •  多路复用的NIO则是上述的普通NIO的补充,

    •  在并发量过大的情况下,不可能每个线程都要轮询自己的IO状态,

    •  这时就可以使用selector管理所有的IO通道channel,

    •  开启一个线程,便可解决成千上万的高并发问题

 

  

AIO:异步IO

  1. 虽然NIO在网络操作中,提供了非阻塞的方法,但是NIO的IO行为还是同步的。

  2. 对于NIO来说,我们的业务线程是在IO操作准备好时,得到通知,接着就由这个线程自行进行IO操作,IO操作本身是同步的。

  3. AIO它不是在IO准备好时再通知线程,而是在IO操作已经完成后,再给线程发出通知,因此AIO是不会阻塞的

  4. 此时我们的业务逻辑将变成一个回调函数,等待IO操作完成后,由系统自动触发,节省了NIO中selector循环遍历检测数据就绪的资源开销

  5. 与NIO不同,当进行读写操作时,只须直接调用API的read或write方法即可。这两种方法均为异步的;

  6. 对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;

  7. 对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。

  8. 即可以理解为,read/write方法都是异步的,完成后会主动调用回调函数。

  

三个IO模型的适用场景 

  • BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。
  • NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
  • AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

转载于:https://www.cnblogs.com/msi-chen/p/10983927.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值