您的位置:首页 > 编程语言 > Java开发

Java NIO 总结

2017-03-28 23:38 127 查看

NIO与原IO的区别

原来的IO和NIO最大的区别在于数据打包和传输的方式。原来的IO是基于流的方式处理数据,而NIO是基于块的方式处理数据。

NIO适用于使用少数线程处理大量连接的情况

Java NIO的核心

Channels

Buffers

Selectors

Java NIO通过事件驱动的方式监听消息,实际上是采用了Reactor模式。各部分的关系如图:



Channel

重要的实现

1. FileChannel:无法设置为非阻塞模式,总是运行在阻塞模式下

2. DatagramChannel:收发UDP数据包的通道

3. SocketChannel:TCP连接客户端通道,可以设置为非阻塞

4. ServerSocketChannel:TCP连接服务端通道,可以设置为非阻塞

特点

1. 既可以从通道中读数据到缓冲区,也可以从缓冲区中写数据到通道;通道支持异步的读写

2. 支持Buffer的Scatter和Gather操作

Buffer

重要的实现

1. 八种中基本数据类型的Buffer

2. MappedByteBuf,用于表示内存映射文件,直接内存方式,速度比较快

特点

1. Buffer的读、写模式是相互对立的,进行反转需要调用flip()方法

2. Buffer的工作原理:capacity,limit,position,需要了解读和写情况下的意义

Selectors

一个Selector能够检测多个Channel

Channel需要在Selector上注册自己感兴趣的事件,事件主要有:Connect,Accept,Read,Write

调用Selector的select方法阻塞等待Channel上的特定事件就绪

select()返回准备就绪的通道个数,调用selector.selectedKeys()返回已经准备就绪的事件

在Selector的open方法中,会根据不同的操作系统提供不同的内部实现,如果是Linux操作系统,则使用Poll(kernel < 2.6)、epoll(kernel > 2.6);如果是window操作系统,则是select,如果是Unix,则是kqueue

Selector的唤醒底层实现

Selector在open()的时候,会建立一个Pipe,通过Pipe实现唤醒。具体参考《Nio Selector阻塞唤醒原理

1. Window下不支持使用Pipe,所以通过两个连接的SocketChannel实现了Pipe,通过本地地址127.0.0.1自己连接自己

2. Linux下则直接使用系统的Pipe进行通信。

Java NIO的缺点

需要自己处理半包和粘包问题。当从通道中读数据到缓冲区的时候,我们并不知道缓冲区中的内容是否是一个完整的包,需要自己手动的进行处理。

这些问题可以通过Netty进行解决
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息