java-nio在Android上使用的种种弊端

我们知道,手机上的网络一般会比较慢(使用wifi除外),用户非常不希望自己在使用手机时被考验耐心。那么在手机上写网络相关的程序就比写pc端的网络程序就有更高的要求——必须在短时间内给用户一个结果,或成功或失败。把这点诉求转化成程序层面的语言,不外乎以下几条:

  1. 程序本身被写得必须高效;
  2. 底层库必须提供可控的超时设置(包括连接超时和读取超时);
  3. 底层库函数本身必须高效;

对于程序员来说,最根本的还是首先要抓好第1点,把自己的程序写好。但除此之外,还需要关注自己所用的底层库在程序所适配的各个平台是否符合上述第2,3条。

笔者最近在使用java里的nio库就碰到了上述的2,3问题,最终不得不放弃。其缺陷表现为以下两点,它们分别对应了上述的2,3问题:

  • NIO并不提供连接超时设置,你需要自己实现[注1];通过SocketChannel.open()获得的套接字可以设置读取超时,但是这类套接字在read超时的时候read返回0,而不像一般套接字那样抛出SocketTimeoutException,这点大家在阻塞地调用这类套接字的read函数时需要注意[注2]
  • NIO库的SocketChannel.java只是java 1.4标准中的一个抽象类,具体实现要靠底层来实现,而各个平台的实现并不相同[注3]。在4.0以下的系统里,SocketChannel.connect函数内部在执行实际的连接之前,如果发现传入的远程地址是一个IP,会先进行DNS反向查询(以便对该IP对应的host进行安全检查),代码如下:
1
2
3
4
5
6
String hostName = ipAddr.getHostName();
// security check
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkConnect(hostName, port);
}

4.0以后的android系统可能考虑到了效率的关系,将这部分代码移除掉了。

另外,在笔者使用它的过程中碰到了多处抛出CancelledKeyException的地方,包括调用Selector.select()函数,包括在检查套接字是否可连接时(也即,调用SocketChannel.isConnectable),可能还有其他的笔者未发现到的地方,这点也需要大家注意。

总之,不推荐大家在Android上使用NIO,不可知的因素比较多;如果很想使用,请多测试。

脚注列表:

注1:笔者通过排序堆结合Selector.select(int timeout)中的timeout进行动态设置来实现的。
注2:笔者的情况是只用NIO来实现连接建立,而读写操作用多线程同步的方式进行,所以很关注read的异常反应形式。
注3:比如在Android系统中,实现的类名叫做SocketChannelImpl,尽管如此,各个版本Android系统中SocketChannelImpl.java的实现也并不完全相同。

nio 弊端的更多相关文章

  1. 第二章 NIO入门

    传统的同步阻塞式I/O编程 基于NIO的非阻塞编程 基于NIO2.0的异步非阻塞(AIO)编程 为什么要使用NIO编程 为什么选择Netty 第二章 NIO 入门 2.1 传统的BIO编程 2.1.1 ...

  2. 关于NIO

    操作系统的IO控制 在整个IO控制方式的发展过程中,始终贯穿着这样一条宗旨:即尽量减少主机对IO控制的干预,把主机从繁杂的IO控制事务中解脱出来,以便更多地去完成数据处理任务.为了缓和高速CPU和IO ...

  3. Java NIO:浅析I/O模型

    也许很多朋友在学习NIO的时候都会感觉有点吃力,对里面的很多概念都感觉不是那么明朗.在进入Java NIO编程之前,我们今天先来讨论一些比较基础的知识:I/O模型.下面本文先从同步和异步的概念 说起, ...

  4. Netty中BIO,NIO

    同步阻塞io(BIO).伪异步io(PIO).非阻塞io(NIO).异步io(AIO)的概念及区别? 同步阻塞io(BIO):服务器端与客户端通过三次握手后建立连接,连接成功,双方通过I/O进行同步阻 ...

  5. java的nio之:浅析I/O模型

    也许很多朋友在学习NIO的时候都会感觉有点吃力,对里面的很多概念都感觉不是那么明朗.在 进入Java NIO编程之前,我们今天先来讨论一些比较基础的知识:I/O模型.下面本文先从同步和异步的概念 说起 ...

  6. (基础篇 走进javaNIO)第二章-NIO入门

    在本章巾,我们会分别对 JDK 的BIO ,NIO 和JDK 1.7 最新提供的 NI02.0的使用进行详细说明 ,通过流程图和代 码讲解,让大 家体会到随着 Ja va 1/0 类库的 不断发展和改 ...

  7. (转)Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码)

    原文出自:http://blog.csdn.net/anxpp/article/details/51512200 1.BIO编程 1.1.传统的BIO编程 网络编程的基本模型是C/S模型,即两个进程间 ...

  8. IO 和 NIO 的思考

    输入输出是操作系统不可或缺的一部分,大致分为两类:面向磁盘和面向网络.在 Java 中有3种 I/O 类型:BIO.NIO 和 AIO,分别是同步阻塞.同步非阻塞和异步非阻塞 I/O,这里着重描述 B ...

  9. Java异步NIO框架Netty实现高性能高并发

    原文地址:http://blog.csdn.net/opengl_es/article/details/40979371?utm_source=tuicool&utm_medium=refer ...

随机推荐

  1. 并发编程中.net与java的一些对比

    Java在并发编程中进行使用java.util.concurrent.atomic来处理一些轻量级变量 如AtomicInteger AtomicBoolean等 .Net中则使用Interlocke ...

  2. C#中获得机器的字符编码webName信息

    在一次解决编码的问题过程中,发现Encoding.GetEncoding("GB2312") == Encoding.GetEncoding("GBK"),到底 ...

  3. http://www.cnblogs.com/zhaoguihua/tag/%E9%AB%98%E6%80%A7%E8%83%BD%E7%BD%91%E7%AB%99/

    http://www.cnblogs.com/zhaoguihua/tag/%E9%AB%98%E6%80%A7%E8%83%BD%E7%BD%91%E7%AB%99/

  4. Finish 和 Complete 的区别

    2012年,在伦敦举行的语言大赛中,圭亚那选手Samsunder Balgobin 在回答比赛中最后一道问题   "你如何用一种容易让人理解的方式解释 complete与finished 的区別"时, ...

  5. 循序渐进Python3(十一) --0-- web之html

    HTML: HTML是英文Hyper Text Mark-up Language(超文本标记语言)的缩写,他是一种制作万维网页面标准语言(标记). 相当于定义统一的一套规则,大家都来遵守他,这样就可以 ...

  6. char、varchar、nchar、nvarchar的区别

    http://www.cnblogs.com/mekong/archive/2009/04/17/1437996.html

  7. Flyweight(享元)--对象结构型模式

    1.意图 运用共享技术有效地支持大量细粒度的对象. 2.动机 Flyweight模式描述了如何共享对象,使得可以细粒度地使用它们,而无需高昂的代价.flyweight是一个共享对象,它可以同时在多个场 ...

  8. app 要求字体使用楷体,使用字体包

    1,下载字体包     http://www.3987.com/xiazai/6/fonts/36616.html#down 2.  studio中src\main\创建assets\fonts,存放 ...

  9. Java基础知识系列——String

    最近晚上没有什么事(主要是不加班有单身),就复习了一下Java的基础知识.我复习Java基础知识主要是依据Java API和The Java™ Tutorials. 今天是第一篇,复习了一下Strin ...

  10. MYSQL-5.5二进制包安装

    groupadd mysql 添加用户组 useradd mysql -s /sbin/nologin -g mysql -M  添加用户 mv mysql-5.5.54-linux2.6-x86_6 ...