java nio
Java NIO与IO的区别:
传统的IO:需要为每个连接建立一个线程,当并发数量巨大时,对内存及线程切换的开销巨大,NIO提供线程池,不再为每个连接建立单独的线程,提供了非阻塞的能力。
Java NIO:非阻塞型I/O的异步输入输出机制
一、传统阻塞I/O:BIO通信
服务端通常由一个单独的Acceptor线程负责监听所有客户端的连接,如果没有连接则会一直阻塞,接收到客户端的连接请求后为每个客户端创建一个新的线程进行链路处理,处理完成后通过输出流返回给客户端,线程销毁,通信模型图如下:
该模型最大的问题在于当客户端访问量急剧增长时,线程数急剧膨胀,系统性能急剧下降。
二、Java NIO的核心组件:
Buffer:缓冲区
Channels:所有的IO在NIO中都从一个Channel开始,Channel有点像流,数据可以从Channel读到Buffer,也可以从Buffer读到Channel
Selectors:允许单个线程处理多个Channel
其中Selector、可选择的Channel通道、SlectionKey配合使用可以实现并发的非阻塞I/O能力。
2、Buffer:缓冲区,是一个抽象类,7个子类分别对应7中基本数据类型,每一个Buffer相当于一个数据容器,核心是一块内存区,可以直接对其执行与内存有关的操作。
有3个重要的属性:
(1)capacity:Buffer的容量、大小
(2)position:数据读写的当前位置
(3)limit:写模式下limit等于capacity,读模式下limit为写入数据的大小
3、Channel:Buffer与I/O服务之间的通道,具有双向性,可以写入,也可以读出。
(1)Java NIO的通道类似流,可以从通道中读取数据到Buffer,也可以将Buufer中的数据写入Channel,可以异步读写。
(2)Channel实现:下面两种通道都实现了SelectedChannel,是可选择的(可选择的注册自己感兴趣的事件)通道,工作在异步方式时不必等到输入、输出完毕才返回,并且可以将自己感兴趣的事件注册到Selector上。
(3)分为两大类:
1>用于网络读写的SelectableChannel:
SocketChannel:能通过TCP读取网络中的数据
ServerSocketChannel:监听新进来的TCP连接,对每一个新进来的连接都会创建一个SocketChannel
2>用于文件读写的FileChannel
4、Selector:实现并发非阻塞I/O的核心,能够检测一到多个通道,并能够知晓通道是否为读写做好准备的组件,只需要一个线程负责Selector的轮询。
Selector不断轮询在其上注册的Socket通道,如果某个Channel上有新的TCP连接接入或者读写事件,这个Channel就处于就绪状态,然后通过SelectionKey获取就绪的Channel集合,进行后续的I/O操作。
5、使用实例:http://www.open-open.com/lib/view/open1380595640713.html
NIO服务端通信序列图:
客户端创建序列图: