NIO和AIO

BIO的阻塞问题
无论是客户端还是服务器,同一时间只能发送或者接受一个信息。处于等待回复的间隔,便是"阻塞"问题。
即使使用多线程的方式 服务器端的accept()、read()方法依旧会被阻塞。

NIO同步非阻塞——是对BIO同步阻塞的改进
NIO,又称为多路复用I/O模型。
应用场景:适用于"高并发"场景 ,其他情况NIO没有明显优势
NIO:数据从通道读入缓冲区,从缓冲区写入通道。

channel通道 ——>缓冲区(bytebuffer)——>channel通道
|
先write(),后read()

  • Channel通道:用于应用程序与操作系统进行交互的渠道。
  • buffer缓冲区:保证每个通道的读写速度。
  • Selector选择器:实现Channel与指定的I/O事件进行绑定。

通道类似于流,但是有区别:
1.通道既可以读数据,也可以写数据。但是流的读写操作是单向的。
2.通道可以异步读取
3.通道的数据总是要经过缓冲区

利用NIO结合文件映射到内存中实现复制文件

private  static  void nioCopy(String sourcePath, String destPath) throws Exception{     
File source = new File(sourcePath);
File dest = new File(destPath);
if(!dest.exists()) {
dest.createNewFile();
}
FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(dest);
FileChannel sourceCh = fis.getChannel(); //读同道
FileChannel destCh = fos.getChannel();//写通道
//将文件映射到内存中
MappedByteBuffer mbb = sourceCh.map(FileChannel.MapMode.READ_ONLY, 0, sourceCh.size());
destCh.write(mbb);
sourceCh.close();
destCh.close();
}

网络编程
多线程网络服务器,服务器对每一次客户端请求都会产生一个新的线程专门来处理它.
这样的弊端:
a.为每一个客户端使用一个线程,如果客户端出现延时等异常,线程可能会被长时间占用。
b.客户端数量众多,可能会消耗大量的系统资源。
解决方法:

  • 使用非阻塞的NIO
  • 数据准备好了再工作

NIO会利用Selector准备好数据后,再交给应用处理;如果数据没准备好Selector会一直处于wait()状态,成功准备好数据后返回SelectionKey,再通过SelectionKey匹配对应的Channel,而一个Channel可以和文件或者网络Socket对应。同时Selector是支持复用的。

AIO异步非阻塞
特性:读取数据之后,再通知我;它本质上没有加快IO
异步的体现:

  • 同步的I/O流 服务器端不会"主动"联系客户端 ,但是AIO在数据准备完成后,会主动通知”客户端“
  • 异步的I/O是交给OS处理,而异步应用自己会处理。

AIO与NIO的区别:
AIO与NIO都是通过管道的方式进行I/O操作,但是AIO每一个处理器与通道都是独立的、一 一对映,NIO是通过选择器进行匹配。

NIO和AIO的区别_非阻塞