Java NIO (十四)NIO 和 IO 的區別和適用場景分析

在研究Java NIO和IO API時,很快就會想到一個問題:

什么時候應該使用IO,什么時候應該使用NIO?

在本文中,我將嘗試闡明Java NIO和IO之間的區別,它們的用例以及它們如何影響代碼的設計。 ###Java NIO和IO之間的主要區別 下表總結了Java NIO和IO之間的主要區別。 我將在表格后面的部分詳細介紹每個區別。

IONIO
面向流利用緩沖區
阻塞IO非阻塞IO
Selectors

###流導向vs緩沖導向 Java NIO和IO之間的第一大區別是IO是面向流的,其中NIO是面向緩沖區的。 那么,這是什么意思?

面向流的Java IO意味著您一次從流中讀取一個或多個字節。 你所做的讀字節取決于你。 他們沒有被緩存在任何地方。 而且,您不能前后移動數據流。 如果您需要前后移動從流中讀取的數據,則需要先將其緩存在緩沖區中。

Java NIO的面向緩沖區的方法略有不同。 數據被讀入一個緩沖區,稍后進行處理。 您可以根據需要前后移動緩沖區。 這給你在處理過程中更多的靈活性。 但是,您還需要檢查緩沖區是否包含您需要的所有數據,以便對其進行全面處理。 而且,您需要確保在將更多數據讀入緩沖區時,不會覆蓋尚未處理的緩沖區中的數據。 ###阻塞vs非阻塞IO Java IO的各種流都被阻塞。 這意味著,當一個線程調用一個read()或write()時,該線程被阻塞,直到有一些數據要讀取,或者數據被完全寫入。 線程在此期間不能做其他事情。

Java NIO的非阻塞模式使得線程可以請求從一個通道讀取數據,并且只獲取當前可用的數據,或者根本沒有任何數據可用。 線程可以繼續使用別的東西,而不是在數據可用于讀取之前保持阻塞狀態。

無阻塞寫入也是如此。 一個線程可以請求將一些數據寫入一個通道,但不要等待它被完全寫入。 線程然后可以繼續,同時做其他事情。

線程在沒有被IO阻塞的情況下花費空閑時間,通常是在其他通道上同時執行IO。 也就是說,一個線程現在可以管理多個輸入輸出通道。

###Selectors Java NIO的選擇器允許單線程監視多個輸入通道。 您可以使用選擇器注冊多個通道,然后使用單個線程“選擇”可用于處理的輸入通道,或者選擇準備寫入的通道。 這個選擇器機制使單個線程可以輕松管理多個通道。 ###NIO和IO如何影響應用程序設計 無論您選擇NIO還是IO作為您的IO工具包,都可能會影響您應用程序設計的以下方面:

  1. API調用NIO或IO類。
  2. 數據的處理。
  3. 用于處理數據的線程數。 ###API調用 當然,使用NIO時的API調用看起來不同于使用IO時的調用。 這并不奇怪。 而不只是從例如數據字節讀取字節。 一個InputStream,數據必須首先被讀入一個緩沖區,然后從那里被處理。 ###數據處理 當使用純粹的NIO設計時,數據的處理也會受到IO設計的影響。

在IO設計中,您從InputStream或Reader讀取字節的數據字節。 想象一下,你正在處理一系列基于行的文本數據。 例如:

Name: Anna
Age: 25
Email: anna@mailserver.com
Phone: 1234567890
復制代碼

這條文本行可以像這樣處理:

InputStream input = ... ; // get the InputStream from the client socketBufferedReader reader = new BufferedReader(new InputStreamReader(input));String nameLine   = reader.readLine();
String ageLine    = reader.readLine();
String emailLine  = reader.readLine();
String phoneLine  = reader.readLine();
復制代碼

注意處理狀態是由程序執行的程度決定的。 換句話說,一旦第一個reader.readLine()方法返回,您肯定知道已經讀取了一整行文本。 readLine()阻塞直到讀完整行,這就是為什么。 你也知道這行包含名字。 同樣,當第二個readLine()調用返回時,您知道該行包含年齡等

正如你所看到的,只有當有新的數據要讀取時,程序才會進行,并且每一步你都知道數據是什么。 一旦正在執行的線程通過讀取代碼中的某段數據,線程就不會在數據中倒退(大部分不是)。 這個原理在這個圖中也有說明:

NIO的實現看起來不同。 這是一個簡單的例子:

ByteBuffer buffer = ByteBuffer.allocate(48);int bytesRead = inChannel.read(buffer);
復制代碼

注意從通道讀取字節到ByteBuffer的第二行。 當該方法調用返回時,您不知道所需的所有數據是否在緩沖區內。 所有你知道的是,緩沖區包含一些字節。 這使得處理有點困難。

想象一下,如果在第一次讀取(緩沖區)調用之后,所有讀入緩沖區的內容都是半行。 例如,"Name: An"。 你能處理這些數據嗎? 不是真的。 你需要等待,直到完整的一行數據已經進入緩沖區,才有意義處理任何數據。

那么如何知道緩沖區中是否包含足夠的數據才能處理? 那么,你沒有。 唯一的辦法就是查看緩沖區中的數據。 結果是,您可能需要多次檢查緩沖區中的數據,才能知道所有數據是否在內部。 這既是低效的,而且在程序設計方面可能變得混亂。 例如:

ByteBuffer buffer = ByteBuffer.allocate(48);int bytesRead = inChannel.read(buffer);while(! bufferFull(bytesRead) ) {bytesRead = inChannel.read(buffer);
}
復制代碼

bufferFull()方法必須跟蹤有多少數據被讀入緩沖區,并根據緩沖區是否已滿而返回true或false。 換句話說,如果緩沖區準備好處理,則認為已滿。

bufferFull()方法掃描緩沖區,但必須保持緩沖區處于與調用bufferFull()方法之前相同的狀態。 否則,讀入緩沖區的下一個數據可能無法在正確的位置讀入。 這不是不可能的,但這是另一個需要注意的問題。

如果緩沖區已滿,可以進行處理。 如果它沒有滿,那么你可能能夠部分處理任何數據,如果這在你的特定情況下是有意義的。 在許多情況下,它不是。

圖中顯示了is-data-in-buffer-ready循環:

###概要 NIO允許您僅使用一個(或幾個)線程來管理多個通道(網絡連接或文件),但代價是解析數據可能比從阻塞流讀取數據時要復雜一些。

如果你需要管理數以千計的同時打開的連接,每一個只發送一點點的數據,例如聊天服務器,在NIO中實現服務器可能是一個優勢。 同樣,如果你需要保持與其他計算機的大量開放連接,例如 在P2P網絡中,使用單個線程來管理所有出站連接可能是一個優勢。 這一個線程,多個連接設計如下圖所示:

如果您的連接帶寬非常高,一次發送大量數據,那么傳統的IO服務器實現可能是最合適的。 該圖說明了一個經典的IO服務器設計:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/452209.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/452209.shtml
英文地址,請注明出處:http://en.pswp.cn/news/452209.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

面向對象三種模型之間的關系

功能模型指明了系統應該“做什么”;動態模型明確規定了什么時候(即在何種狀態下接受了什么事件的觸發)做;對象模型則定義了做事情的實體。在面向對象方法學中,對象模型是最基本最重要的,它為其他兩種模型奠定了基礎,人…

android node

pkg install nodejs-current轉載于:https://www.cnblogs.com/insight0912/p/9231342.html

springmvc 中@Controller和@RestController的區別

1.Controller, RestController的共同點 都是用來表示Spring某個類的是否可以接收HTTP請求 2.Controller, RestController的不同點 Controller標識一個Spring類是Spring MVC controller處理器 RestController: a convenience annotation that does nothing more …

easyUI 日期控件修改...

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 個人覺得easyUI挺好用的。 它的中文文檔地址: http://www.zi-han.net/case/easyui/ 日期本來效果是這樣的: 改…

面向對象分析的三個模型與5個層次

在面向對象分析中,主要由對象模型、動態模型和功能模型組成。對象模型是最基本、最重要、最核心的。 面向對象建模得到的模型包含系統的3個要素,即靜態結構(對象模型)、交互次序(動態模型)和數據變換(功能模型)。解決的問題不同,這3個子模型…

學成在線--15.課程計劃查詢

文章目錄一.需求分析二.頁面原型1.tree組件介紹2.webstorm配置jsx三.API接口1.數據模型2.自定義模型類3.接口定義四.sql語句五.服務器端1.Dao1)Mapper接口2)Mapper映射文件2.Service3.Controller4.測試六.前端1.Api方法2.Api調用1)定義查詢課…

團隊作業-項目答辯

1. 王書磊 1600802063 http://www.cnblogs.com/wsl-1117/ 劉令斌 1600802017 http://www.cnblogs.com/liulingbin/ 許浩然 1600802066 https://www.cnblogs.com/xuhaoran1/ 成明龍 1600802038 http://www.cnblogs.com/CMLCML/ 2這是我們的效果圖. 3.(1)修…

Java構造和解析Json數據的兩種方法詳解一

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 在www.json.org上公布了很多JAVA下的json構造和解析工具,其中org.json和json-lib比較簡單,兩者使用上差不多但還是…

面向對象方法開發的方法

面向對象分析首要的工作,是建立問題域的對象模型。 這個模型描述了現實世界中的“類與對象”以及它們之間的關系,表示了目標系統的靜態數據結構。靜態數據結構對應用細節依賴較少,比較容易確定。因此,用面向對象方法開發絕大多數…

程序員編程需要多少個小時?

Michael Arrington曾發表一篇博文說,創業者必須加倍的努力工作,甚至不惜趴在辦公桌上睡覺,這樣才能成功。對此,我并不贊同其觀點,我看了很多評論都是關于這樣工作會適得其反,不但沒有獲得成功,相…

事務以及@Transcational注解

文章目錄1.事務的概念2.事務的四個特性3.關于Transcational注解的理解4.使用場景5.舉例6.編程式事務管理7.相關知識1.事務的概念 事務,是指作為單個邏輯工作單元執行的一系列操作,結果只有成功和失敗兩種,要么全部成功(全部提交)&#xff0c…

提高代碼復用率

由于現在的互聯網企業業務比較繁忙,導致產品狗不停地提需求,還總是改來改去,最后留給程序猿的時間少之又少。程序猿也不是吃素的,干脆直接copy一下代碼隨便搞一下實現功能就行,也談不上所謂的精心設計了。這樣的確是縮…

java 對 redis 的基本操作

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 一、server端安裝 1、下載https://github.com/MSOpenTech/redis 可看到當前可下載版本:redis2.6 2、安裝 1)解壓…

JsRender 前端渲染模板常用API學習

JsRender 常用API 1. $.templates() $.templates()方法是用來注冊或編譯模板的,使用的情況有以下幾種。 把html字符串編譯編譯成模板獲取使用script標簽聲明的模板,并返回一個模板對象把html字符串或者在script標簽中聲明的模板注冊成命名模板獲取之前就…

狀態圖

狀態圖(Statechart Diagram)是描述一個實體基于事件反應的動態行為,顯示了該實體如何根據當前所處的狀態對不同的事件做出反應。通常我們創建一個UML狀態圖是為了以下的研究目的:研究類、角色、子系統、或組件的復雜行為。

我身邊的手機應用開發者

手機應用火了,我身邊的一位朋友(A君)也投身到開發者行列,不過他還算聰明并沒有辭掉工作專做手機應用軟件開發。 其原因在于他們領導打算做一款自己的應用軟件,正當A君愁到底是做IOS平臺還是Android平臺的時候,領導說:…

學成在線--16.添加課程計劃

文章目錄一.需求分析二.API接口三.后端1.Dao2.Service3.Controller4.測試四.前端1.頁面原型說明1)添加按鈕2)視圖部分3)在數據模型中添加如下變量4)定義表單提交方法和重置方法2.Api調用1)定義 api方法2)調…

mac 下的操作

nodejs在Mac下的卸載 在 node 官網上下載的安裝包,用安裝包安裝的node.應該可以用一下命令行卸載: 在終端輸入以下命令: sudo rm -rf /usr/local/{bin/{node,npm},lib/node_modules/npm,lib/node,share/man/*/node.*} 刪除/usr/local/lib中的…

理解 maven 的核心概念

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 本文以類圖的方式,介紹 maven 核心的 12 個概念及相互之間的關系。 Table of Contents 1 maven管理的目標:工程…

時間跟蹤圖

事件跟蹤圖實質上是擴充的腳本,可以認為事件跟蹤圖是簡化的UML順序圖。