<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0
    數據加載中……

    Java網絡編程從入門到精通(31):非阻塞I/O簡介

    本文為原創(chuàng),如需轉載,請注明作者和出處,謝謝!

    上一篇:Java網絡編程從入門到精通(30):定制accept方法

        在網絡應用中,一般可以采用同步I/O(阻塞I/O)和非阻塞I/O兩種方式進行數據通訊。這兩種方式并非互相排斥和互相取代。我們可以在平時的應用中單獨采用其中一種通訊方式,也可以混合使用這兩種通訊方式。在本文中就什么是非阻塞I/O以及為什么要使用這種通訊方式進行了介紹,在下一篇文章中給出了一個簡單的例子來演示在網絡應用中如何使用非阻塞I/O進行通訊。

    一、什么是非阻塞I/O

    我們可以將同步I/O稱為阻塞I/O,非阻塞I/O稱為異步I/O。在本書中采用了比較常用的叫法:同步I/O和非阻塞I/O。雖然它們的叫法不同,但含義是一樣的。讀者在閱讀其他書時應注意這一點。

    在講解什么是非阻塞I/O之前,首先應了解什么是同步I/O,這里的同步指的是什么。同步這個概念在程序設計中主要是指代碼按順序執(zhí)行的過程。如在Java程序中的main方法,如果不使用多線程,這個方法中的代碼一定是從前往后按順序執(zhí)行的。這就叫做同步。如果使用了多線程,從宏觀角度來看會有不同的代碼段同時執(zhí)行,這就叫做異步。在同步I/O中的同步概念也類似,也就是說,在I/O通訊過程中,只要是某一步的通訊未結束,就無法進行其他的通訊。那么這里的同步指的是什么呢?要回答這個問題之前,首先讓我們先回憶一下,在網絡通訊中有哪些地方可能會被阻塞。如果讀者看了前面的章節(jié)就會知道答案。對于客戶端來說,有兩個地方可能會被阻塞:連接服務器(調用connect方法時)和讀寫數據。而在服務端也有兩個地方可能會被阻塞:等待客戶端請求(調用accept方法時)和讀寫數據(在一般情況下,寫數據不會被阻塞,但如果網絡環(huán)境比較差的時候,客戶端和服務端的寫數據操作也可能發(fā)生阻塞現象)。也就是說,可以設置超時時間的地方就可能被阻塞。而同步I/O中的同步就是指除了以下兩種情況外程序會一直處于等待狀態(tài):

    1. 連接服務器、讀寫數據或等待客戶端請求正常地執(zhí)行。

    2. 在等待超時時間后,拋出了超時異常。

    在上面我們了解了什么是同步I/O。而非阻塞I/O和同步I/O最明顯的不同就是同步I/O所有可能被阻塞的地址在非阻塞I/O中都不會被阻塞。如在讀取數據時,如果數據暫時無法被讀取。那么在非阻塞I/O中會立刻返回,以便程序可以執(zhí)行其他的代碼,然后系統(tǒng)會不斷偵測這個未完成的讀取操作,直到可以繼續(xù)讀數據時再來完成這個操作。

    JavaJDK1.4及以后版本中提供了一套API來專門操作非阻塞I/O,我們可以在java.nio包及其子包中找到相關的類和接口。由于這套APIJDK新提供的I/O API,因此,也叫New I/O,這就是包名nio的由來。這套API由三個主要的部分組成:緩沖區(qū)(Buffers)、通道(Channels)和非阻塞I/O的核心類組成。這三部分的詳細內容將在本章的后面介紹。

    二、為什么要使用非阻塞I/O

    在使用同步I/O的網絡應用中,如果要同時處理多個客戶端請求,或是在客戶端要同時和多個服務器進行通訊,就必須使用多線程來處理。也就是說,將每一個客戶端請求分配給一個線程來單獨處理。這樣做雖然可以達到我們的要求,但同時又會帶來另外一個問題。由于每創(chuàng)建一個線程,就要為這個線程分配一定的內存空間(也叫工作存儲器),而且操作系統(tǒng)本身也對線程的總數有一定的限制。如果客戶端的請求過多,服務端程序可能會因為不堪重負而拒絕客戶端的請求,甚至服務器可能會因此而癱瘓。

    當然,可以使用線程池(將在第三部分講解)來緩解服務器的壓力,但這并不能解決客戶端因訪問過于密集而造成的服務器拒絕響應的問題。雖然在服務端還有請求緩沖區(qū)作為保障,但這個緩沖區(qū)的大小是有限的(一般為50),如果客戶端的請求數遠超過這個數,客戶端還是會收到拒絕服務的信息。

    在這種情況下,使用非阻塞I/O就可以解決這個問題。由于使用非阻塞I/O的程序一般是單線程的(有時可能將使用非阻塞I/O的程序段放到一個單獨的線程里,而主線程負責處理用戶的輸入),因此,服務端接收的客戶端請求數并不隨著工作線程數的增加而增加。所以使用非阻塞I/O模式就不會受到操作系統(tǒng)對線程總數的限制,也不會占用大量的服務器資源。

    非阻塞I/O雖然可以到達在處理大量客戶端請求的同時,又不占用大量的服務器資源的目的。但這種通訊方式并不能完全取代同步I/O。如非阻塞I/O并不適合象FTP服務器那樣需要保持連接狀態(tài)的應用(原因將在以后的章節(jié)中說明)。非阻塞I/O一般應用在服務端比較多一些,因為客戶端一般并不需要處理大量的連接(但某些應用除外,如象百度、GoogleWeb Spider,需要同時下載多個網頁,這時就需要在客戶端建立大量的連接來滿足需求),而服務端程序一般需要接收并處理大量的客戶端請求,因此,就需要使用多線程(使用同步I/O)或非阻塞I/O來達到這個目的。如果某個服務端應用處理的客戶端請求沒那么多時,使用多線程和同步I/O可能會更好一點,因為這種方式要比非阻塞I/O方式更靈活。

    在前面一直將非阻塞I/O和網絡應用放到一起講。其實非阻塞I/O并不等于網絡。我們也可以將非阻塞I/O應用到非網絡的應用中,如文件復制。由于同步I/O是基于字節(jié)流的,而非阻塞I/O是基于緩沖區(qū)和通道的。因此,從理論上,所操作的文件越大,非阻塞I/O的優(yōu)勢越能體現出來。而對于比較小的文件操作,這兩種方式的效率差不多。根據實驗得知,復制一個4G左右的文件,一般情況下,非阻塞I/O方式比同步I/O方式快大約15%左右。

    下一篇:
    Java網絡編程從入門到精通(32):一個非阻塞I/O的例子





    Android開發(fā)完全講義(第2版)(本書版權已輸出到臺灣)

    http://product.dangdang.com/product.aspx?product_id=22741502



    Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


    新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

    posted on 2009-08-16 10:46 銀河使者 閱讀(3125) 評論(2)  編輯  收藏 所屬分類: java 原創(chuàng)網絡編程

    評論

    # re: Java網絡編程從入門到精通(31):非阻塞I/O簡介  回復  更多評論   

    不錯uoa
    2009-08-16 11:03 | 99讀書人

    # re: Java網絡編程從入門到精通(31):非阻塞I/O簡介  回復  更多評論   

    第二部分第三段用的是同步I/O吧
    2015-04-22 15:21 | 老干爹
    主站蜘蛛池模板: 131美女爱做免费毛片| 永久在线毛片免费观看| 亚洲色欲色欲www| 亚洲av高清在线观看一区二区| 手机看片国产免费永久| 亚洲免费观看在线视频| 亚洲视频在线一区二区| 99久久人妻精品免费一区| 久久久久亚洲精品无码网址色欲 | 亚洲成色在线影院| 欧美大尺寸SUV免费| caoporn成人免费公开| 亚洲一区免费视频| 超清首页国产亚洲丝袜| 在线免费观看污网站| 日本高清高色视频免费| 污污的视频在线免费观看| 亚洲乱人伦精品图片| 国产亚洲精品高清在线| 一二三四免费观看在线视频中文版 | 亚洲一区无码中文字幕乱码| 亚洲色一色噜一噜噜噜| 成年18网站免费视频网站| 国产情侣久久久久aⅴ免费| 亚洲av色香蕉一区二区三区蜜桃| 久久精品亚洲日本佐佐木明希| 国产美女无遮挡免费网站| 2020因为爱你带字幕免费观看全集| 水蜜桃视频在线观看免费| 亚洲人成电影在线观看网| 亚洲精品无码Av人在线观看国产 | 成人AV免费网址在线观看| 精品国产免费一区二区三区香蕉| 无码天堂亚洲国产AV| 中文字幕无码精品亚洲资源网久久| 亚洲福利在线视频| 亚洲熟伦熟女新五十路熟妇 | 久久久久亚洲精品中文字幕| 女人18毛片水真多免费看| 嘿嘿嘿视频免费网站在线观看 | 亚洲A∨午夜成人片精品网站|