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. 如何使用SQLPLUS分析SQL语句(查询执行计划跟踪)

    方法一:autotrace 1,  connect sys/密码 as sysdba,在sys用户下运行$ORACLE_HOME/sqlplus/admin/plustrce.sql这段sql的实际内 ...

  2. eclipse的快捷键(写给eclipse新手)

    Eclipse常用的快捷键 1.常用的快捷键 Alt+/:常用于补全单词.方法,以及内容辅助,可以省很多事情 Ctrl+1:用于全局,快速修正 Ctrl+D  删除整行 Ctrl+F   用于全局 , ...

  3. Ionic打包过程下载Gradle失败的解决方法

      安卓应用现在很多都是基于gradle进行大包,ionic默认的打包命令 cordova  build --release  android 就是使用gradle进行打包,但同时ionic也支持in ...

  4. CMD打包文件,解压文件

    压缩%ProgramFiles%\Winrar\rar a c:\123.rar c:\123解压%ProgramFiles%Winrar\unrar.exe x c:\sp\sp.rar c:\sp

  5. Peterson算法

    #define FALSE 0 #define TRUE 1 #define N 2 /*进程数量 */ int turn; /* 现在轮到谁 */ int interested[N]; /*所有值初 ...

  6. Logstash 父子关系 配置

    最近在使用Lostash的过程中遇到了一个问题:在一个log文件里包含两类数据,而且两类数据之间存在父子关系,那如何使用lostash的configuration实现这个需求呢 思路: 首先定义父事件 ...

  7. C. Dima and Salad 背包好题

    http://codeforces.com/contest/366/problem/C 在n个物品中选出若干个,使得sum(a[i]) = k * sum(b[i]) 把问题转化一下就是,求sum(a ...

  8. (转载)AppScan使用分享

    转载:http://www.cnblogs.com/fnng/archive/2012/10/09/2717568.html 这里主要分享如何使用AppScan对一大项目的部分功能进行安全扫描. -- ...

  9. MM常用BADI

    1.删除采购申请BADI BAPI_REQUISITION_DELETE 但是需要输入采购申请 和采购申请行项目号

  10. 修改 TeamViewer ID方法

    修改 TeamViewer ID 的方法: 1. 开始 > 运行,录入%appdata%,删除TeamViewer的文件夹:2. 开始 > 运行,录入regedit:    删除 HKEY ...