分享
 
 
 

Java I/O API之性能分析

王朝java/jsp·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

要:

IO API的可伸缩性对Web应用有着极其重要的意义。Java 1.4版以前的API中,阻塞I/O令许多人失望。从J2SE 1.4版本开始,Java终于有了可伸缩的I/O API。本文分析并计算了新旧I/O API在可伸缩性方面的差异。

提纲:

一、概述

二、用旧API编写的HTTP服务器

三、非阻塞的HTTP服务器

四、注册与处理过程详解

五、可伸缩性的定量分析和比较

正文:

一、概述

IO API的可伸缩性对Web应用有着极其重要的意义。Java 1.4版以前的API中,阻塞I/O令许多人失望。从J2SE 1.4版本开始,Java终于有了可伸缩的I/O API。本文分析并计算了新旧IO API在可伸缩性方面的差异。Java向Socket写入数据时必须调用关联的OutputStream的write()方法。只有当所有的数据全部写入时,write()方法调用才会返回。倘若发送缓冲区已满且连接速度很低,这个调用可能需要一段时间才能完成。假如程序只使用单一的线程,其他连接就必须等待,即使那些连接已经做好了调用write()的预备也一样。为了解决这个问题,你必须把每一个Socket和一个线程关联起来;采用这种方法之后,当一个线程由于I/O相关的任务被阻塞时,另一个线程仍然能够运行。

尽管线程的开销不如进程那么大,但是,考虑到底层的操作平台,线程和进程都属于消耗大量资源的程序结构。每一个线程都要占用一定数量的内存,而且除此之外,多个线程还意味着线程上下文的切换,而这种切换也需要昂贵的资源开销。因此,Java需要一个新的API来分离Socket与线程之间过于紧密的联系。在新的Java I/O API(java.nio.*)中,这个目标终于实现了。

本文分析和比较了用新、旧两种I/O API编写的简单Web服务器。由于作为Web协议的HTTP不再象原来那样只用于一些简单的目的,因此这里介绍的例子只包含要害的功能,或者说,它们既不考虑安全因素,也不严格遵从协议规范。

二、用旧API编写的HTTP服务器

首先我们来看看用旧式API编写的HTTP服务器。这个实现只使用了一个类。main()方法首先创建了一个绑定到8080端口的ServerSocket:

public static void main() throws IOException {

ServerSocket serverSocket = new ServerSocket(8080);

for (int i=0; i < Integer.parseInt(args[0]); i++) {

new Httpd(serverSocket);

}

}

接下来,main()方法创建了一系列的Httpd对象,并用共享的ServerSocket初始化它们。在Httpd的构造函数中,我们保证每一个实例都有一个有意义的名字,设置默认协议,然后通过调用其超类Thread的start()方法启动服务器。此举导致对run()方法的一次异步调用,而run()方法包含一个无限循环。

在run()方法的无限循环中,ServerSocket的阻塞性accpet()方法被调用。当客户程序连接服务器的8080端口,accept()方法将返回一个Socket对象。每一个Socket关联着一个InputStream和一个OutputStream,两者都要在后继的handleRequest()方法调用中用到。这个方法将读取客户程序的请求,经过检查和处理,然后把合适的应答发送给客户程序。假如客户程序的请求合法,通过sendFile()方法返回客户程序请求的文件;否则,客户程序将收到相应的错误信息(调用sendError())方法。

while (true) {

...

socket = serverSocket.accept();

...

handleRequest();

...

socket.close();

}

现在我们来分析一下这个实现。它能够出色地完成任务吗?答案基本上是肯定的。当然,请求分析过程还可以进一步优化,因为在性能方面StringTokenizer的声誉一直不佳。但这个程序至少已经关闭了TCP延迟(对于短暂的连接来说它很不合适),同时为外发的文件设置了缓冲。而且更重要的是,所有的线程操作都相互独立。新的连接请求由哪一个线程处理由本机的(因而也是速度较快的)accept()方法决定。除了ServerSocket对象之外,各个线程之间不共享可能需要同步的任何其他资源。这个方案速度较快,但令人遗憾的是,它不具有很好的可伸缩性,其原因就在于,很显然地,线程是一种有限的资源。

三、非阻塞的HTTP服务器

下面我们来看看另一个使用非阻塞的新I/O API的方案。新的方案要比原来的方案稍微复杂一点,而且它需要各个线程的协作。它包含下面四个类:

·NIOHttpd

·Acceptor

·Connection

·ConnectionSelector

NIOHttpd的主要任务是启动服务器。就象前面的Httpd一样,一个服务器Socket被绑定到8080端口。两者主要的区别在于,新版本的服务器使用java.nio.channels.ServerSocketChannel而不是ServerSocket。在利用bind()方法显式地把Socket绑定到端口之前,必须先打开一个管道(Channel)。然后,main()方法实例化了一个ConnectionSelector和一个Acceptor。这样,每一个ConnectionSelector都可以用一个Acceptor注册;另外,实例化Acceptor时还提供了ServerSocketChannel。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有