<b>Java网络编程从入门到精通(31):非阻塞I/O简介</b>[Java编程]
本文“<b>Java网络编程从入门到精通(31):非阻塞I/O简介</b>[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
在网络利用中,普通可以采取同步I/O(阻塞I/O)和非阻塞I/O两种方法举行数据通讯.这两种方法并非彼此排挤和彼此代替.我们可以在平常的利用中单独采取此中一种通讯方法,也可以混合利用这两种通讯方法.在本文中就什么是非阻塞I/O以及为什么要利用这种通讯方法举行了介绍,在下一篇文章中给出了一个简单的例子来演示在网络利用中若何利用非阻塞I/O举行通讯.
1、什么是非阻塞I/O
我们可以将同步I/O称为阻塞I/O,非阻塞I/O称为异步I/O.在本书中采取了对比常用的叫法:同步I/O和非阻塞I/O.固然它们的叫法差别,但含义是一样的.读者在阅读其他书时应注意这一点.
在讲授什么是非阻塞I/O之前,首先应理解什么是同步I/O,这里的同步指的是什么.同步这个概念在程序计划中主如果指代码按次序履行的历程.如在Java程序中的main办法,假如不利用多线程,这个办法中的代码一定是早年往后按次序履行的.这就叫做同步.假如利用了多线程,从宏观角度来看会有差别的代码段同时履行,这就叫做异步.在同步I/O中的同步概念也近似,也就是说,在I/O通讯历程中,只如果某一步的通讯未完毕,就无法举行其他的通讯.那么这里的同步指的是什么呢?要答复这个问题之前,首先让我们先回想一下,在网络通讯中有哪些地方大概会被阻塞.假如读者看了前面的章节就会知道答案.关于客户端来说,有两个地方大概会被阻塞:衔接服务器(调用connect办法时)和读写数据.而在服务端也有两个地方大概会被阻塞:等候客户端恳求(调用accept办法时)和读写数据(在普通情形下,写数据不会被阻塞,但假如网络环境对比差的时刻,客户端和服务端的写数据操作也大概发生阻塞现象).也就是说,可以设置超不时间的地方便大概被阻塞.而同步I/O中的同步就是指除了以下两种情形外程序会一向处于等候状况:
1. 衔接服务器、读写数据或等候客户端恳求正常地履行.
2. 在等候超不时间后,抛出了超时非常.
在上面我们理解了什么是同步I/O.而非阻塞I/O和同步I/O最明显的差别就是同步I/O全部大概被阻塞的地址在非阻塞I/O中都不会被阻塞.如在读取数据时,假如数据暂时无法被读取.那么在非阻塞I/O中会立即返回,以便程序可以履行其他的代码,然后系统会不断侦测这个未完成的读取操作,直到可以持续读数据时再来完成这个操作.
Java在JDK1.4及今后版本中供应了一套API来专门操作非阻塞I/O,我们可以在java.nio包及其子包中找到相关的类和接口.由于这套API是JDK新供应的I/O API,因此,也叫New I/O,这就是包名nio的由来.这套API由三个主要的部份构成:缓冲区(Buffers)、通道(Channels)和非阻塞I/O的核心类构成.这三部份的具体内容将在本章的背面介绍.
2、为什么要利用非阻塞I/O
在利用同步I/O的网络利用中,假如要同时处理多个客户端恳求,或是在客户端要同时和多个服务器举行通讯,就必须利用多线程来处理.也就是说,将每一个客户端恳求分配给一个线程来单独处理.这样做固然可以到达我们的要求,但同时又会带来别的一个问题.由于每成立一个线程,就要为这个线程分配一定的内存空间(也叫工作存储器),并且操作系统本身也对线程的总数有一定的限制.假如客户端的恳求过量,服务端程序大概会因为不堪重负而回绝客户端的恳求,乃至服务器大概会因此而瘫痪.
当然,可以利用线程池(将在第三部份讲授)来减缓服务器的压力,但这并不能办理客户端因拜候过于密集而造成的服务器回绝呼应的问题.固然在服务端还有恳求缓冲区作为保障,但这个缓冲区的大小是有限的(普通为50),假如客户端的恳求数远超越这个数,客户端还是会收到回绝服务的信息.
在这种情形下,利用非阻塞I/O便可以办理这个问题.由于利用非阻塞I/O的程序普通是单线程的(有时大概将利用非阻塞I/O的程序段放到一个单独的线程里,而主线程负责处理用户的输入),因此,服务端接纳的客户端恳求数并不随着工作线程数的增添而增添.所以利用非阻塞I/O情势就不会遭到操作系统对线程总数的限制,也不会占用大量的服务器资源.
非阻塞I/O固然可以到达在处理大量客户端恳求的同时,又不占用大量的服务器资源的目的.但这种通讯方法并不能完好代替同步I/O.如非阻塞I/O并不合适象FTP服务器那样需求保持衔接状况的利用(缘由将在今后的章节中阐明).非阻塞I/O普通利用在服务端对比多一些,因为客户端普通并不需求处理大量的衔接(但某些利用除外,如象百度、Google的Web Spider,需求同时下载多个网页,这时就需求在客户端成立大量的衔接来满意需求),而服务端程序普通需求接纳并处理大量的客户端恳求,因此,就需求利用多线程(利用同步I/O)或非阻塞I/O来到达这个目的.假如某个服务端利用处理的客户端恳求没那么多时,利用多线程和同步I/O大概会更好一点,因为这种方法要比非阻塞I/O方法更机动.
在前面一向将非阻塞I/O和网络利用放到一同讲.其实非阻塞I/O并不等于网络.我们也可以将非阻塞I/O利用到非网络的利用中,如文件复制.由于同步I/O是基于字节俭的,而非阻塞I/O是基于缓冲区和通道的.因此,从理论上,所操作的文件越大,非阻塞I/O的上风越能表现出来.而关于对比小的文件操作,这两种方法的效率差不多.按照实行得知,复制一个4G左右的文件,普通情形下,非阻塞I/O方法比同步I/O方法快大约15%左右.
以上是“<b>Java网络编程从入门到精通(31):非阻塞I/O简介</b>[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |