漫話:如何給女朋友解釋什麼是BIO、NIO和AIO?
週末午後,在家裡面進行電話面試,我問了面試者幾個關於IO的問題,其中包括什麼是BIO、NIO和AIO?三者有什麼區別?具體如何使用等問題,但是面試者回答的並不是很滿意。於是我在面試評價中寫道:"對Java的IO提醒理解不夠深入"。恰好被女朋友看到了。
Java IO
IO,常協作I/O,是Input/Output的簡稱,即輸入/輸出。通常指資料在內部儲存器(記憶體)和外部儲存器(硬碟、優盤等)或其他周邊裝置之間的輸入和輸出。
輸入/輸出是資訊處理系統(例如計算機)與外部世界(可能是人類或另一資訊處理系統)之間的通訊。
輸入是系統接收的訊號或資料,輸出則是從其傳送的訊號或資料。
在Java中,提供了一些列API,可以供開發者來讀寫外部資料或檔案。我們稱這些API為Java IO。
IO是Java中比較重要,且比較難的知識點,主要是因為隨著Java的發展,目前有三種IO共存。分別是BIO、NIO和AIO。
Java BIO
BIO 全稱Block-IO 是一種同步且阻塞的通訊模式。是一個比較傳統的通訊方式,模式簡單,使用方便。但併發處理能力低,通訊耗時,依賴網速。
Java NIO
Java NIO,全程 Non-Block IO ,是Java SE 1.4版以後,針對網路傳輸效能優化的新功能。是一種非阻塞同步的通訊模式。
NIO 與原來的 I/O 有同樣的作用和目的, 他們之間最重要的區別是資料打包和傳輸的方式。原來的 I/O 以流的方式處理資料,而 NIO 以塊的方式處理資料。
面向流的 I/O 系統一次一個位元組地處理資料。一個輸入流產生一個位元組的資料,一個輸出流消費一個位元組的資料。
面向塊的 I/O 系統以塊的形式處理資料。每一個操作都在一步中產生或者消費一個數據塊。按塊處理資料比按(流式的)位元組處理資料要快得多。但是面向塊的 I/O 缺少一些面向流的 I/O 所具有的優雅性和簡單性。
Java AIO
Java AIO,全程 Asynchronous IO,是非同步非阻塞的IO。是一種非阻塞非同步的通訊模式。
在NIO的基礎上引入了新的非同步通道的概念,並提供了非同步檔案通道和非同步套接字通道的實現。
三種IO的區別
首先,我們站在巨集觀的角度,重新畫一下重點:
BIO (Blocking I/O):同步阻塞I/O模式。
NIO (New I/O):同步非阻塞模式。
AIO (Asynchronous I/O):非同步非阻塞I/O模型。
那麼,同步阻塞、同步非阻塞、非同步非阻塞都是怎麼回事呢?關於這部分內容也可以檢視《漫話:如何給女朋友解釋什麼是IO中的阻塞、非阻塞、同步、非同步?》。
同步阻塞模式:這種模式下,我們的工作模式是先來到廚房,開始燒水,並坐在水壺面前一直等著水燒開。
同步非阻塞模式:這種模式下,我們的工作模式是先來到廚房,開始燒水,但是我們不一直坐在水壺前面等,而是回到客廳看電視,然後每隔幾分鐘到廚房看一下水有沒有燒開。
非同步非阻塞I/O模型:這種模式下,我們的工作模式是先來到廚房,開始燒水,我們不一一直坐在水壺前面等,也不隔一段時間去看一下,而是在客廳看電視,水壺上面有個開關,水燒開之後他會通知我。
阻塞VS非阻塞:人是否坐在水壺前面一直等。
同步VS非同步:水壺是不是在水燒開之後主動通知人。
適用場景
BIO方式適用於連線數目比較小且固定的架構,這種方式對伺服器資源要求比較高,併發侷限於應用中,JDK1.4以前的唯一選擇,但程式直觀簡單易理解。
NIO方式適用於連線數目多且連線比較短(輕操作)的架構,比如聊天伺服器,併發侷限於應用中,程式設計比較複雜,JDK1.4開始支援。
AIO方式適用於連線數目多且連線比較長(重操作)的架構,比如相簿伺服器,充分呼叫OS參與併發操作,程式設計比較複雜,JDK7開始支援。
使用方式
使用BIO實現檔案的讀取和寫入。
//Initializes The ObjectUser1 user = new User1();user.setName("hollis");user.setAge(23);System.out.println(user);//Write Obj to FileObjectOutputStream oos = null;try { oos = new ObjectOutputStream(new FileOutputStream("tempFile")); oos.writeObject(user);} catch (IOException e) { e.printStackTrace();} finally { IOUtils.closeQuietly(oos);}//Read Obj from FileFile file = new File("tempFile");ObjectInputStream ois = null;try { ois = new ObjectInputStream(new FileInputStream(file)); User1 newUser = (User1) ois.readObject(); System.out.println(newUser);} catch (IOException e) { e.printStackTrace();} catch (ClassNotFoundException e) { e.printStackTrace();} finally { IOUtils.closeQuietly(ois); try { FileUtils.forceDelete(file); } catch (IOException e) { e.printStackTrace(); }}//Initializes The ObjectUser1 user = new User1();user.setName("hollis");user.setAge(23);System.out.println(user);//Write Obj to FileObjectOutputStream oos = null;try { oos = new ObjectOutputStream(new FileOutputStream("tempFile")); oos.writeObject(user);} catch (IOException e) { e.printStackTrace();} finally { IOUtils.closeQuietly(oos);}//Read Obj from FileFile file = new File("tempFile");ObjectInputStream ois = null;try { ois = new ObjectInputStream(new FileInputStream(file)); User1 newUser = (User1) ois.readObject(); System.out.println(newUser);} catch (IOException e) { e.printStackTrace();} catch (ClassNotFoundException e) { e.printStackTrace();} finally { IOUtils.closeQuietly(ois); try { FileUtils.forceDelete(file); } catch (IOException e) { e.printStackTrace(); }}
使用NIO實現檔案的讀取和寫入。
static void readNIO() { String pathname = "C:\\Users\\adew\\Desktop\\jd-gui.cfg"; FileInputStream fin = null; try { fin = new FileInputStream(new File(pathname)); FileChannel channel = fin.getChannel(); int capacity = 100;// 位元組 ByteBuffer bf = ByteBuffer.allocate(capacity); int length = -1; while ((length = channel.read(bf)) != -1) { bf.clear(); byte[] bytes = bf.array(); System.out.write(bytes, 0, length); System.out.println(); } channel.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fin != null) { try { fin.close(); } catch (IOException e) { e.printStackTrace(); } } } } static void writeNIO() { String filename = "out.txt"; FileOutputStream fos = null; try { fos = new FileOutputStream(new File(filename)); FileChannel channel = fos.getChannel(); ByteBuffer src = Charset.forName("utf8").encode("你好你好你好你好你好"); int length = 0; while ((length = channel.write(src)) != 0) { System.out.println("寫入長度:" + length); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }
使用AIO實現檔案的讀取和寫入
public class ReadFromFile { public static void main(String[] args) throws Exception { Path file = Paths.get("/usr/a.txt"); AsynchronousFileChannel channel = AsynchronousFileChannel.open(file); ByteBuffer buffer = ByteBuffer.allocate(100_000); Future<Integer> result = channel.read(buffer, 0); while (!result.isDone()) { ProfitCalculator.calculateTax(); } Integer bytesRead = result.get(); System.out.println("Bytes read [" + bytesRead + "]"); }}class ProfitCalculator { public ProfitCalculator() { } public static void calculateTax() { }}public class WriteToFile { public static void main(String[] args) throws Exception { AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open( Paths.get("/asynchronous.txt"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE); CompletionHandler<Integer, Object> handler = new CompletionHandler<Integer, Object>() { @Override public void completed(Integer result, Object attachment) { System.out.println("Attachment: " + attachment + " " + result + " bytes written"); System.out.println("CompletionHandler Thread ID: " + Thread.currentThread().getId()); } @Override public void failed(Throwable e, Object attachment) { System.err.println("Attachment: " + attachment + " failed with:"); e.printStackTrace(); } }; System.out.println("Main Thread ID: " + Thread.currentThread().getId()); fileChannel.write(ByteBuffer.wrap("Sample".getBytes()), 0, "First Write", handler); fileChannel.write(ByteBuffer.wrap("Box".getBytes()), 0, "Second Write", handler); }}
滴滴滴,水開了。
相關推薦
漫話:如何給女朋友解釋什麼是BIO、NIO和AIO?
週末午後,在家裡面進行電話面試,我問了面試者幾個關於IO的問題,其中包括什麼是BIO、NIO和AIO?三者有什麼區別?具體如
漫話:給女朋友解釋為什麼隨機播放歌曲並不隨機
週末,開車帶女朋友出去玩,車裡面,隨機播放著周杰倫的歌曲。我正沉浸在『得兒飄,得兒飄,得兒意的飄』中,幻想著自己是秋名山車神,突然,旁邊的豆腐,哦不,女朋友說話了。
BIO、NIO和AIO
IO的方式通常分為幾種,同步阻塞的BIO、同步非阻塞的NIO、非同步非阻塞的AIO。 一、BIO 在JDK1.4出來之前,我們建立網路連線的時候採用BIO模式,需要先在服務端啟動一個ServerSocket,然後在客戶端啟動Socket來對服務端進行通訊,預設情
BIO、NIO和AIO的區別、具體實現
一:理解同步:同步就是在發出一個*呼叫*時,在沒有得到結果之前,該*呼叫*就不返回,但是一旦呼叫返回,就得到返回值了。簡單的為:就是由*呼叫者*主動等待這個*呼叫*的結果。 二:非同步:*呼叫*在發出之後,這個呼叫就直接返回了,所以沒有返回結果;換句話說,當一個非同步過程呼
BIO、NIO和AIO的區別(簡明版)
一:事件分離器 在IO讀寫時,把 IO請求 與 讀寫操作 分離調配進行,需要用到事件分離器。根據處理機制的不同,事件分離器又分為:同步的Reactor和非同步的Proactor。 Reactor模型: - 應用程式
Java的BIO、NIO和AIO介紹
1. I/O概念理解:同步/非同步、阻塞/非阻塞 一個IO操作其實分成了兩個步驟:發起IO請求和實際的IO操作。 同步IO和非同步IO的區別就在於第二個步驟是否阻塞,如果實際的IO讀寫阻塞請求程序,那麼就是同步IO。 阻塞IO和非阻塞IO的區別在於第一步,發
java高併發實戰(八)——BIO、NIO和AIO
由於之前看的容易忘記,因此特記錄下來,以便學習總結與更好理解,該系列博文也是第一次記錄,所有有好多不完善之處請見諒與留言指出,如果有幸大家看到該博文,希望報以參考目的看瀏覽,如有錯誤之處,謝謝大家指出與留言。一、什麼是NIO?NIO是New I/O的簡稱,與舊式的基於流的I/
Java中BIO、NIO和AIO的區別和應用場景
最近一直在準備面試,為了使自己的Java水平更上一個檔次,拜讀了李林峰老師的《Netty權威指南》,瞭解了Java關於IO的發展和最新的技術,真是受益匪淺,現在把我總結的關於BIO、NIO和AIO的區別
BIO、NIO和AIO的區別
IO的方式通常分為幾種,同步阻塞的BIO、同步非阻塞的NIO、非同步非阻塞的AIO。 一、BIO 在JDK1.4出來之前,我們建立網路連線的時候採用BIO模式,需要先在服務端啟動一個ServerSocket,然後在客戶端啟動Socket來對服務端進行通訊,預設情況
漫話:如何給女朋友解釋什麼是併發和並行
某天下班後,我在家裡進行電話面試,問到面試者這樣一個問題:"能不能簡單介紹一下你理解的併發和並行,並說明一下他們之間的關係"。但是面試者回答的並不好,所以我在面試評價中寫到:"對併發和並行的概念不清楚"。這時,女朋友看到這句話。 併發和並行最開始都是作業系統中的概念,表示的是CPU執
基礎 | BIO、NIO與AIO
Java中的IO部分比較複雜,具體可參看書籍《Java NIO》和《Netty權威指南》。在此,僅對BIO、NIO和AIO進行概述性梳理,未涉及到具體實現細節,後續有空將深入展開。 同步IO和非同步IO 參考答案: IO操作主要分為兩個步驟,即發起IO請求和實際I
BIO、NIO與AIO的區別
IO的方式通常分為幾種,同步阻塞的BIO、同步非阻塞的NIO、非同步非阻塞的AIO。 同步思想:就是當程式處理完一個請求或者操作的時候,再返回給使用者。使用者等待時間長,且不能關閉該程式或者這個頁面,必須等 待該請求執行完,才能關閉或
轉BIO,NIO和AIO講的很明白的文章
到底什麼是“IO Block” 很多人說BIO不好,會“block”,但到底什麼是IO的Block呢?考慮下面兩種情況: 用系統呼叫read從socket裡讀取一段資料 用系統呼叫read從一個磁碟檔案讀取一段資料到記憶體 如果你的直覺告訴你,這兩種都算“Block”,
結合程式碼詳細聊聊BIO,NIO和AIO
作者:大寬寬 1、到底什麼是“IO Block” 很多人說BIO不好,會“block”,但到底什麼是IO的Block呢?考慮下面兩種情況: 用系統呼叫read從socket裡讀取一段資料 用系統呼叫read從一個磁碟檔案讀取一段資料到記憶體 如果你的直覺告
Java中BIO,NIO和AIO使用樣例
上文中分析了阻塞,非阻塞,同步和非同步概念上的區別以及各種IO模型的操作流程,本篇文章將主要介紹Java中BIO,NIO和AIO三種IO模型如何使用。需要注意的是,本文中所提到的所有樣例都是在一個server對應一個client的情況下工作的,如果你想擴充套件為一個se
IO、NIO和AIO的區別
IO和NIO的區別:其本質就是阻塞和非阻塞的區別。 阻塞概念:應用程式在獲取網路資料的時候,如果網路傳輸資料很慢,那麼久一直等著,知道傳輸完畢為止。 非阻塞概念:應用程式直接可以獲取已經準備就緒好的資料,無需等待。(從作業系統緩衝區中直接讀取已經緩衝完畢的資料,不用阻塞等待
漫話:如何給女朋友解釋為什麼雙11無法修改收貨地址
2018年11月11日上午11點,我拖著疲憊身軀回到家中,準備美美的睡上一覺,洗去身上值班一宿而帶來的疲憊。突然想到之前有交代女朋友讓她幫我搶東西,不知道怎麼樣了。 QPS、TR、併發使用者數、最佳執行緒數等等這些都是系統對併發處理上有關的概念。可以用來
漫話:如何給女朋友解釋為什麼雙11當天不能申請退款
雙十一當天晚上的十一點多,我下班回到家中,看到平時很早就睡覺的女朋友今天竟然還沒有睡覺。於是我問她: 服務降級:當伺服器壓力劇增的情況下,根據實際業務情況及流量,對一些服務和頁面有策略的不處理或換種簡單的方式處理,從而釋放伺服器資源以保證核心交易正常運作或高效運作。
漫話:如何給女朋友解釋什麼是DDoS攻擊?
週五下班比較早,我正在家裡面玩吃雞遊戲,正在瘋狂的跑毒,這時候坐在旁邊刷著抖音的女朋友問了我一個奇怪的問題。 分散式拒絕服務(DDoS:Distributed Denial of Service)攻擊,是指攻擊者利用大量“肉雞”對攻擊目標發動大量的正常或非正常請求、耗盡目標主機資
漫話:如何給女朋友解釋什麼是RPC
週末一大早,我正在電腦前面看新聞,突然女朋友大喊起來:哇,杭州下大雪啦,快來看啊。我並沒有理她,於是她跑過來拉我。 雪後杭州 RPC 是Remote Procedure Call的縮寫,譯為遠端過程呼叫。是一個計算機通訊協議。