首页 > 技术文章 > java Nio

dhh-blog 2017-04-08 21:43 原文

java Nio的组成

Buffer

Channel

Selector

Buffer就是缓冲区,Channel读写数据的存放地,在IO中我们读取数据采用的是stream,不能重复读取,一次性读完,但是buffer不是一次性读完的,使用时必须使用while循环不断的判断buffer里面是否还存在数据。buffer的存在读模式和写模式。

Channel分为两类,一类是fileChannel,只能工作在阻塞模式;一类是socketChannel,可以选择工作在非阻塞模式或者阻塞模式,与selector使用时必须得配置在非阻塞模式,不然会爆出异常。Channel的生命周期:新建,使用,关闭。channel的新建可以通过channels.open()的方法实现,但是fileChannel的是实现只能在fileStream中打开。Channel的关闭可以通过Channel.close()方法,关闭后,连接将丢失,通道将不可用。close()方法是一个阻塞方法,且同步。若一个通道是一个InterruptibleChannel时,当线程在该通道上发生中断或者中断标志位被设立,则通道关闭,线程抛出异常。当通道关闭时,所有阻塞在该通道上的线程将wakeUp,并抛出异常。

Selector是多路复用选择器,进行就绪检查并通知,线程安全,但是它的selectionKey集合并不是线程安全的,多个线程访问这些集合时需要使用同步。Selector的生命周期:新建,注册通道,使用关闭。选择器的创建基于操作系统,通过spi来实现的。通过channel.register()方法将通道与Selector关联起来,关联关系采用SelectionKey来抽象,一个SelectionKey包含两个以整数编码的比特掩码,一个表示通道感兴趣的操作,一个表示已经准备好的操作。一个Selector的维护三个键集合:感兴趣键,已经选择的键,已经取消的键;Selector.select()该方法是一个阻塞方法,当操作系统没有IO操作,线程将进行阻塞直到有操作进行。阻塞在select()方法上的线程可以通过Selector.wakeup()方法消除阻塞,当wakeUp()时线程已经进行完了select()操作,则将取消下一次调用select()的阻塞。Selector.close()方法将关闭所有与该Selector相关联的通道,所有阻塞在这些通道上的线程将被唤醒。

推荐阅读