传统服务器实现是BIO和多线程方式(一个socket一个线程),这种模式又很大的限制,首先BIO阻塞线程严重影响服务器性能,以及多线程的方式,当并发线程数大起来后会致使系统频繁的在线程以前切换,一样会影响系统性能。
Java1.4后引入Nio API,经过使用非阻塞实现IO快速读写,为高并发服务器提供了很好的解决方案。
Java Nio API由Buffer, Channel和Selector组成,Java只是提供了一个规范,部分方法并未实现,Sun Nio则实现了Java Nio。
Buffer做为缓冲区将数据缓存起来,从而作到数据的非阻塞读写;Channel则对应文件句柄,包括file,socket等,每一个Channel自带Buffer,Channel上的读写数据所有存放到Buffer中,Channel和Buffer的组合实现了io的非堵塞;Selector则做为选择器,负责监听Channel上的事件,一个Selector能够管理多个Channel,实现多路复用。
linux
- Buffer:
关键类:
ByteBuffer
CharBuffer
IntBuffer
FloatBuffer
DoubleBuffer
LongBuffer
MappedByteBuffer
Buffer按照分配方式又分为DirectxxxBuffer, HeapxxxBuffer。DirectxxxBuffer是直接分配JVM外的内存,HeapxxxBuffer则是分配JVM堆内存。
结构:

方法:
get( ) 从Buffer中读取数据
put( ) 写数据到Buffer中
flip( ) 将Buffer从写模式切换到读模式
rewind( ) 重置position和mark用于重写数据或者重复读
clear( ) 清空整个缓冲区
compact( ) 清除已经读过的缓冲区
- Channel:
关键类:
SocketChannel
FileChannel
DatagramChannel
ServerSocketChannel
Channel是对文件句柄的封装,每一个Channel对应一个句柄,包括file, socket等。
Channel配合Buffer使用,能够从Channel中读取Buffer和写入Buffer。
方法:
read(buffer) 从Channel中读取数据到buffer中
write(buffer) 将buffer中的数据写入到Channel中
- Selector: 关键类: Selector SelectorProvider Selector用于实现多路复用,能够注册多个Channel,经过select方法返回本身感兴趣的事件,Selector底层在linux上经过epoll实现。 Selector配合SelectionKey使用,SelectionKey记录了事件的类型和事件的Channel。 方法: select( ) 阻塞等待Selector上的事件 selectdKeys( ) 返回Selector上的事件