NIO、AIO概述总结

        经过前几天的学习,将BIO的基础知识总结完成,接下来今天我将总结学习NIO和AIO的知识点,在理解学习的基础上,去使用相关知识点进行编程学习。这次我将先总结NIO的知识点,再学习AIO的相关概念。

NIO

NIO主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector。传统IO基于字节流和字符流进行操作,而NIO基于Channel和Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择区)用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个线程可以监听多个数据通道。 

NIO是采用内存映射文件的方式处理输出输出,可以将文件或者文件的一段区域映射到内存中,然后就可以像访问内存一样来访问文件,所以进行输入输出的速度比BIO快的多。

BIO是同步阻塞式;NIO 是同步非阻塞式
BIO 是面向流的, NIO 是面向缓冲区的
NIO 是一个线程从某个通道发送读取请求时,仅仅获取当前可以用的数据不会保持阻塞等待

1.Channel

Channel可以直接将文件的部分或者全部映射到 buffer中。注意不能直接访问Channel中的数据,包括 读写都不行,Channel只能与buffer进行交互。

常见方法有3map/read/write

public class Test1 { 
    public static void main(String[] args) throws Exception { 
        File file = new File("data/Test1.java"); // 获取channel对象 
        FileChannel inChannel = new FileInputStream(file).getChannel(); 12345
        ByteBuffer buffer = ByteBuffer.allocate(256);// 构建一个容积为256的 buffer 
// 从channel中获取数据写到buffer中。文件可能大于256,所以需要进行多次读取。 可以通过-1判定读取结束 
        while (inChannel.read(buffer) != -1) { // 将buffer中没有数据的部分封印起来 
            buffer.flip(); // 设置limit,limit之后的数据不允许操作 
            System.out.println(buffer.limit()); //256 
            Charset charset = Charset.forName("UTF-8"); // 参数为编码字符集名 称,创建对应编码字符集的解码器 
            CharsetDecoder decoder = charset.newDecoder();//通过Charset创建对应的解码器对象  
            CharBuffer cb = decoder.decode(buffer);// 使用解码器可以将 ByteBuffer转换为   
            CharBuffer System.out.println(cb); 
            buffer.clear();// 清空buffer中的数据,同时将position设置为0,为下一次 读取操作做准备 
        } 
    } 
}

2. Buffer(缓冲区)

Buffer主要作用就是用于转入数据,然后输出数据。最基本的实现是ByteBuffer,可以在字节数组上进行 get/set操作;另外针对基本数据类型,系统提供了7种具体的实现,例如CharBuffer、ShortBuffer、 DoubleBuffer。 

常用方法:capacity():int返回buffer的容积值
hasRemaining():boolean判断是否还有数据可以进行处理
remaing0:int获取position当前位置和limit界限之间的元素个数
position():int返回当前的操作位置
mark():Buffer设置标记位置,已被后面重返这个位置reset():Buffer将位置position重新返回到mark所在为位置rewind():Buffer 将position重新设置到0,并取消mark标记
put(obj):xxxBuffer用于向buffer中添加数据
get():xxx用于从buffer中获取数据

3.Selector

是Java NIO核心组件中的一个,用于检查一个或多个NIO Channel通道的状态是否处于可读、可写。如 此可以实现单线程管理多个channels也就是可以管理多个网络链接。

使用Selector的好处在于: 使用更少的线程来就可以来处理通道了, 相比使用多个线程,避免了线程上下文切换带来的开销

基本用法:

1. Selector的创建。通过调用Selector.open()方法创建一个Selector对象

2. 注册ChannelSelector

3. 轮询方式获取选择器上的状态值

AIO(异步非阻塞式 )

AIO最大的一个特性就是异步能力,这种能力对socket与文件I/O都起作用。AIO其实是一种在读写操作结束之前允许进行其他操作的I/O处理。

JDK7新增了一些和文件、网络IO相关的APIAIO最大的特性就是异步处理能力,一般用于网络编程和大文件IO处理中。AIO其实就是一种在读写操作结束之前允许执行其它操作的IO处理,等读写执行完毕自动通知调用后续处理。

1.将来式异步读取:使用Future用来保存异步操作的处理结果

Path path = Paths.get("data/a1.txt"); // 从语义的角度上说比File好一些,用于封装一个文件或者文件夹对象 
AsynchronousFileChannel channel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); 

ByteBuffer buffer = ByteBuffer.allocate(1024); 
Future<Integer> future = channel.read(buffer, 0); 
int readNum = future.get(); 

buffer.flip(); 
CharBuffer cb = CharBuffer.allocate(1024); 
CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder(); 
decoder.decode(buffer,cb,false);

cb.flip(); 
String ss=new String(cb.array(),0,cb.limit()); 
System.out.println(ss);

2.回调式异步读取:回调式是采用事件处理技术实现的

Path path = Paths.get("data/a1.txt"); // 从语义的角度上说比File好一些,用于封装一个文件或者文件夹对象 
AsynchronousFileChannel channel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); 
ByteBuffer buffer = ByteBuffer.allocate(1024); 
channel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() 
{ 
    // 当读取完成后自动执行的方法 
    public void completed(Integer result, ByteBuffer attachment) {         
        System.out.println(Thread.currentThread().getName() + "读取数据完毕!");
    }// 当读取处理过程中出错时自动执行的方法 
    public void failed(Throwable exc, ByteBuffer attachment) {     
        System.out.println(Thread.currentThread().getName() + "读取数据出现异 常:" + exc); 
    } 
}); 
System.out.println("立即看到结果!"); 
while (true) { 
    System.out.println(Thread.currentThread().getName() + "sleep...."); 
    Thread.sleep(1000); 
}

BIO、NIO、AIO总结

BIO:同步阻塞,实现模式为一个连接一个线程,就是客户端连接请求时,服务器需要启动一个线程进行处理。

NIO:同步非阻塞,实现模式为一个连接一个线程,客户端发起请求时会注册到selector多路复用器上,多路复用器会轮询所有有IO请求时才启动一个线程进行处理。

AIO:异步非阻塞,一个有效请求一个线程,客户端IO请求都是由OS操作系统先完成了再通知服务器应用启动线程进行处理。

区别:

同步阻塞:用户进程发起一个IO操作请求后,必须等待IO操作完成后,用户进程才能继续运行后续操作,否则用户进程阻塞等待。

同步非阻塞:用户进程发起一个IO操作请求后可以返回做其它事情,但是用户进程需要不时询问 IO操作是否已经就绪,这里会造成不必要的CPU资源浪费。

异步非阻塞:用户进程发起一个IO操作请求后可以立即返回做其它事情,等到IO操作真正完成后,应用程序会收到IO操作完成的通知,此时用户进程只需要对数据进行处理即可。

        今天把NIO、AIO的相关知识点总结完成,最后又将BIO、NIO、AIO进行区别总结,流的基本知识就讲到了这里,期待更加深入的学习!同时对之前学过的知识再进行复习巩固,加强练习锻炼。加油!!!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值