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. 【java基础学习一】int[]、Integer[]、String[] 排序( 正序、倒叙)、去重

    调用: //重复项有9.5.1.2 int[] ints = new int[]{9,4,7,8,2,5,1,6,2,5,9,1}; arrayIntTest(ints); ///////////// ...

  2. 关于C#程序无故退出

    今天我发现一种情况,分享下 我一个对象是用多线程写的代码,主程序调用完后有时候也会退出,catch不到.我在原对象的接口里面加上lock之后就ok了!我的理解是该对象申请的资源没释放完毕,加lock后 ...

  3. PRML

    PRML 学习之 第一章 介绍 Introduction #欢迎共同学习和讨论,由于本文将不断修改,谢绝转载 模式识别问题具有重要且久远的历史.比如,16世纪开普勒发现行星运动定律,又如20世纪出发现 ...

  4. git ssh端口号变更之后所需要的修改

    假设原本的repository地址为:git@gitlab.cjx.com:jinxin/project2.git 端口变更之后,需要调整为:ssh://git@gitlab.cjx.com:PORT ...

  5. jquery 之选择器

    一.基本: HTML代码: <p class="p1">p段落</p> <h class="h1">h标签</h> ...

  6. 第二章Java基础之标识符

  7. WeakHashMap回收时机

    import java.util.ArrayList; import java.util.List; import java.util.WeakHashMap; public class TestWe ...

  8. Sharif University CTF 2016 - Smooth As Silk

    Category: Crypto Points: 200 Solves: 11 Description: p > q n = p*q = 1146153281852525177586999436 ...

  9. NLua - 基于Lua的C#脚本引擎

    Nlua NLua is the bind between Lua world and the .NET world. NLua is a fork of project LuaInterface ( ...

  10. nginx实现动静分离

    环境信息如下: 测试目的: 访问jpg文件的时候,会请求到192.168.1.106上面 访问其他文件会请求到192.168.1.103上面 nginx的安装详见前面的文章 nginx的配置如下 wo ...