BIO,NIO与AIO的简介与区别
BIO同步阻塞IO,NIO同步非阻塞IO,BIO异步非阻塞IO;
传统IO和新IO都是用于输入/输出,传统的IO存在没有读到有效数据,程序将会在此处阻塞线程的执行。新IO(NIO)采用文件映射的方式来处理IO,将文件或者文件的一段区域映射到内存中,这样就可以像访问内存一样来访问文件了。通过这种方式就可以提高输入/输出的执行效率。
NIO中包含Channel(通道)和Buffer(缓冲)这两个核心对象。Channel类似于传统的InputStream和OutputStream,其最大的区别在于它提供了一个map()方法,通过map()方法可以直接将"一块数据"映射到内存中。
Buffer可以将其理解为容器,本质是个数组。Channel中读取的数据必须先放到Buffer中,发送到Channel中的所有对象也必须首先放到Buffer中。
NIO结合Selector类可以实现非阻塞式的输入/输出。Selector监控Channel来实现非阻塞IO操作。
AIO实现异步阻塞通信。Java提供了异步Channel支持,异步Channel可以提供更高效的IO,基于异步Channel的IO机制被称为异步IO。
IO分类为:同步IO和异步IO。
对于IO操作分为两步:1.程序发出IO请求;2.完成实际的IO操作。传统IO和NIO分为阻塞IO和非阻塞IO,都是针对请求是否为程序发出IO请求是否阻塞来划分的。同步IO与异步IO的区别在于第二步,异步的IO操作是由操作系统完成,再将结果返回给应用程序,这就是异步IO;如果实际的IO操作需要应用程序本身执行,会阻塞线程,那就是同步IO。
区别:
一、同步阻塞I/O(BIO):
同步阻塞I/O,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过线程池机制来改善。BIO方式适用于连接数目比较小且固定的架构,这种方式对服务端资源要求比较高,并发局限于应用中,在jdk1.4以前是唯一的io现在,但程序直观简单易理解
二、同步非阻塞I/O(NIO):
同步非阻塞I/O,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有IO请求时才启动一个线程进行处理。NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,jdk1,4开始支持
三、异步非阻塞I/O(AIO):
异步非阻塞I/O,服务器实现模式为一个有效请求一个线程,客户端的IO请求都是由操作系统先完成了再通知服务器用其启动线程进行处理。AIO方式适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,jdk1.7开始支持。
四、IO与NIO区别:
IO面向流,NIO面向缓冲区
IO的各种流是阻塞的,NIO是非阻塞模式
Java NIO的选择允许一个单独的线程来监视多个输入通道,可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入或选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道
五、同步与异步的区别:
同步:发送一个请求,等待返回,再发送下一个请求,同步可以避免出现死锁,脏读的发生
异步:发送一个请求,不等待返回,随时可以再发送下一个请求,可以提高效率,保证并发
同步异步关注点在于消息通信机制,
阻塞与非阻塞关注的是程序在等待调用结果时(消息、返回值)的状态:
阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程
不同层次:
CPU层次:操作系统进行IO或任务调度层次,现代操作系统通常使用异步非阻塞方式进行IO(有少部分IO可能会使用同步非阻塞),即发出IO请求后,并不等待IO操作完成,而是继续执行接下来的指令(非阻塞),IO操作和CPU指令互不干扰(异步),最后通过中断的方式通知IO操作的完成结果。
线程层次:操作系统调度单元的层次,操作系统为了减轻程序员的思考负担,将底层的异步非阻塞的IO方式进行封装,把相关系统调用(如read和write)以同步的方式展现出来,然而同步阻塞IO会使线程挂起,同步非阻塞IO会消耗CPU资源在轮询上,3个解决方法;
多线程(同步阻塞)
IO多路复用(select、poll、epoll)
直接暴露出异步的IO接口,kernel-aio和IOCP(异步非阻塞)
Linux IO模型:
阻塞/非阻塞:等待I/O完成的方式,阻塞要求用户程序停止执行,直到IO完成,而非阻塞在IO完成之前还可以继续执行
同步/异步:获知IO完成的方式,同步需要时刻关心IO是否完成,异步无需主动关心,在IO完成时它会收到通知。