java之NIO编程

所谓行文如编程,随笔好比java文件,文章好比类,参考文献是import,那么目录就是方法定义。

本篇文章处在分析thrift的nonblocking server之前,因为后者要依赖该篇文章的知识。若两文同一篇,那即是两类共享同一文件,其中有一个必为public,若一文在另一文中,即为内部类。按编程规范,还是分成两篇来写为好。

java之NIO详解系列文章,比较好的,还是推荐这篇http://tutorials.jenkov.com/java-nio/overview.html。本文只是简略总结一下。一为备忘,二为忘了很快能够拾起。所以遍观本博所写,大都勾画而已,点到即止。所以者何?所谓语言编程,框架工具,异步请求,各种协议,模型演化,参数配置,随用随弃,随拿随起,翻手为云,覆手为雨,三层以上,存而不议,三层而下,勤勤演习。所以者何?孔子曰:君子不器!

上面罗嗦了一番,下面开始进入正题。

java NIO主要部件为Buffer、Channel、Selector。Buffer对应数据,Channel对应连接,Selector是所有向其注册了的Channel的管理器和监控器。

与java IO相比,前者(IO)好比直播,后者就是自己播放,可以前进,可以后退;前者每个连接的操作都是阻塞的,一般做法是单开一个线程处理一个连接,如上一篇的threadpool server的做法,后者可以一个线程管理多个连接,即通过Selector的事件方式管理名下的Channel,把阻塞上移,移到了Selector的select函数中去了。

使用Buffer可以操纵Channel的读写,使用Selector可以监视Channel的事件,下面放一段代码,其意自明。

Selector selector = Selector.open();

channel.configureBlocking(false);

SelectionKey key = channel.register(selector, SelectionKey.OP_READ);

while(true) {

  int readyChannels = selector.select();

  if(readyChannels == 0) continue;

  Set<SelectionKey> selectedKeys = selector.selectedKeys();

  Iterator<SelectionKey> keyIterator = selectedKeys.iterator();

  while(keyIterator.hasNext()) {

    SelectionKey key = keyIterator.next();

    if(key.isAcceptable()) {
// a connection was accepted by a ServerSocketChannel. } else if (key.isConnectable()) {
// a connection was established with a remote server. } else if (key.isReadable()) {
// a channel is ready for reading } else if (key.isWritable()) {
// a channel is ready for writing
} keyIterator.remove();
}
}

跟channel读写关联的比较有用的工具类是Scatter / Gather。可以一读多,可以多写一。

完毕。

上一篇:HDU 3466 Proud Merchants【贪心 + 01背包】


下一篇:HDU 3466 Proud Merchants 带有限制的01背包问题