java中IO、NIO、AIO(NIO2.0)的學習

java中的IO

傳統的IO

我們通常所說的傳統IO編程就是同步阻塞式的I/O編程,也就是一個Socket和一個Client的端到端的通信過程,我們啓動Socket端的時候,Socket會調用accept()方法進行阻塞,等待Client端的請求,直到Client端發送請求過來,然後給於反饋。後來發展出僞異步的I/O編程,也就是把IO編程裏面加上一個自定義的線程池,這樣就可以實現多個Client端的請求然後通過線程池的阻塞讓Socket端一一給於請求反饋。
基礎的Socket和Client代碼我在這裏就不進行寫入了。

僞異步IO

那傳統的這種IO,有了多少個Client端就要創建多少個線程去訪問Socket,在jdk1.5之前沒有NIO的時候,就是用的僞異步的IO來解決這個問題的。在僞異步IO這種解決方案中就是在傳統的Socket中加了一個自定義線程池(可以去我自定義線程池的那篇博客去學習自定義線程池),然後像這個線程池中傳入最大線程數,和BlockingQueue的容量,這樣我們多個Client端訪問我們Socket的時候就會在這個自定義線程池中進行阻塞。這樣就會使得應用程序更加的可控,不至於使服務器被Client端撐爆。當然這種代碼已經是很古老的一種代碼。

JDK1.5的NIO1.0

那我們現在所說的異步非阻塞的編程到底是什麼意思?
其實對於異步非阻塞真正的實現是在jdk1.7以後才真正的實現的。也就是NIO2.0的時候才實現,那麼在NIO1.0的時候也就是JDK1.5的時候我們只是實現了非阻塞並沒有實現異步的概念。

傳統IO和NIO的區別

其實傳統的IO和NIO的區別其本質就是阻塞和非阻塞的區別
阻塞概念:應用程序在獲取網絡數據的時候,如果網絡傳輸很慢,那麼程序就會一直處於等待狀態,直到數據傳輸結束爲止。
非阻塞概念:應用程序直接可以獲取已經準備好的網絡數據,無需等待。
io爲同步阻塞的形式nio爲同步非阻塞的形式。NIO1.0並沒有實現異步的概念,在jdk1.7之後的NIO2.0才真正的實現了異步非阻塞的概念。
同步時:應用程序會直接參與IO讀寫操作,並且我們的程序會直接阻塞到某一個方法上,直到數據準備就緒。或者採用輪詢的策略實時檢查數據的就緒狀態,如果就緒則獲取數據。
異步時:就是所用IO操作交給操作系統處理,我們編寫的應用程序不參與IO的操作,我們的程序不需要關心IO的讀寫,當操作系統完成了IO的讀寫操作時,會給我們的應用程序發送通知,我們的應用程序直接拿走數據即可。
同步說的是你的server服務器端的執行方式。
阻塞說的是具體的技術,接收數據的方式、狀態。

NIO編程介紹

有的人叫NIO爲 New IO,而我們通常認爲NIO是 Not Blocking IO,即非阻塞的IO。
學習NIO編程,我們首先要了解幾個概念。
Buffer(緩衝區):在基本IO操作中,所有的數據都是以流的形式操作的,而在NIO中,則都是使用緩衝區,所有的讀寫操作都是使用緩衝區完成的。緩衝區本質上是一塊可以寫入數據,然後可以從中讀取數據的內存。這塊內存被包裝成NIO Buffer對象,並提供了一組方法,用來方便的訪問該塊內存。
Channel(管道,通道):是一個TCP連接之間的抽象,一個Tcp連接可以對應多個Channel,而不是以前的方式只有一個通信信道,這個時候就減少TCP了連接的次數。
Selector(選擇器,多路複用器):輪詢所有的註冊通道,根據通道狀態執行相關操作。狀態包括:Connect,Accept,Read,Write。

在server端會創建一個Selector多路複用器,所有的客戶端想和服務器建立連接都要創建一個SocketChannel註冊到Selector上,然後Selector使用一個線程輪詢着檢測所有的註冊的SocketChannel的狀態,根據每個不同的通道的狀態執行相關的代碼。NIO的本質就是避免原始的TCP建立連接使用三次握手的操作,減少連接的開銷。

AIO編程介紹

服務端:AsynchronousServerSocketChannel
客戶端:AsynchronousSocketChannel
用戶處理器:CompletionHandler接口,這個接口實現應用程序向操作系統發起io請求。當完成後處理具體的邏輯。否則做自己該做的事情。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章