IO模型之NIO快速理解

2021-10-05 12:15:49 字數 2668 閱讀 2923

什麼是nio?

nio是乙個非阻塞的就是說,他在accept()的時候不會阻塞,在read()的時候也不會阻塞,和之前的bio不同。

假設有一萬個連線,如果是bio那核心就必須丟擲1萬個執行緒去處理,但是nio確不用,他可能只需要幾百個就行。

為什麼nio可以做到這樣呢?是因為nio的3大核心。

//nio : non-blocking io 這是在socket網路 核心機制中

//nio : new io 這是在jdk中的稱呼核心

在之前是得到乙個socket物件,然後得到乙個輸入流乙個輸出流,但是這個channel提供讀的能力和寫的能力,而且還帶乙個bytebuffer,這裡bytebuffer不做太細的解說了,後面還會記錄的。

既可以從通道裡把資料讀到bytebuffer,還可以在bytebuffer裡把資料加工處理後在寫到通道裡,如下圖所示:

補充說下:一般乙個channel(通道)對應乙個bytebuffer,但是多個通道對應乙個bytebuffer也可以不過要進行竄行化的處理。

下面先來講一下單執行緒版本的nio,就是只有乙個執行緒在處理連線和資料的讀寫,但是不會阻塞原因是什麼呢?看下面的示例**。
nio其實主要是通過設定***configureblocking(false)***來做到非阻塞的。

服務端會一直迴圈的去看有沒有客戶端連上來,如果有連上來的就放到乙個集合裡,如果沒有就返回-1,然後進行下一次迴圈,所以不會阻塞。

放到集合裡去之後,然後會去遍歷這個集合如果在通道裡讀到東西了就放到bytebuffer裡去沒有的話就返回-1,讀完資料的時候要filp()翻轉一下,這個是為了讓上圖中position的這個復位,bytebuffer裡的資料用完之後要清空bytebuffer給下乙個用客戶端用。

缺點分析:上面這種存在乙個很大的問題就是資源的浪費,比如說當有c10k(一萬個)個連線時,每次都要去迴圈一次,但是不一定有客戶端連上來而且也不一定有資料讀,而且每個客戶端讀一次資料的複雜度是o(1)那一萬個的複雜度就是o(c10k),假設c10k中只有2個要讀,那資源就是很浪費。如果把連線比做路的話,這個就好比是100條路,每條路長10公尺,然後都要你自己去跑,去看哪條路有或者然後去卸貨,那這樣的話就會很麻煩,那怎麼解決這個問題呢? 這個時候就引出了乙個多路復用器的概念,這個是什麼意思呢,就是說你可以把這所有的路一下子全交給乙個呼叫由這個呼叫去告訴你那條路需要讀了,這個多路復用器就像是收費站一樣。

那麼這個多路復用器是什麼呢?在作業系統核心裡是什麼呢?

裡面注意一下io是同步的處理是非同步的futuer

不管nio還是bio都要有乙個listen狀態的server,第一步把server交給select,select是乙個系統呼叫,調select的時候就把6fd傳到核心去了,核心就會告訴你有沒有人建立連線給你返回,select會告訴你6上有事了,然後會給你返回乙個7fd,然後把7fd也放到select裡去,6裡面關注有沒有人連線,7裡面關注有沒有資料到達,這個時候read的複雜度就不是o(n)的了,假設有兩個人告訴你要讀就是o(2),這個減少的是什麼呢是程式調核心、程式調核心的次數,也就是使用者態和核心態的乙個切換,就像之前一樣每條路你都要跑回來在跑過去看,但是現在不用了,現在只需要跟收費站說下,有車需要卸貨告訴我一下。這個就是多路復用器。

就是只有乙個執行緒去處理一下圖里的事情。

2.1 混合模型
什麼是混合模型?就是有乙個執行緒既充當boss也充當worker。

2.1 主從模型
什麼是多執行緒的selector呢?相比前面的當執行緒的做的事情就是乙個執行緒去處理連線資料的讀寫,而這裡的多執行緒就是有乙個執行緒相當於乙個管家(boss),它不做別的,只負責accept()客戶端連線,而其他執行緒就是工作者,會處理客戶端的資料的讀寫等事件。

這個具體是在 做的呢? 就是當listen完之後,會把server註冊到boss的selector上,然後每隔一段時間,這個boss就會去輪詢一次看看有沒有要連線的客戶端,如果有的話就把它連上去,然後放到乙個佇列裡去,然後就由這個worker去取出來將它註冊到worker的selector上。

當然這個selector也可以有多個,原理是一樣的。其實netty就和這個已經有點像了。

IO模型之BIO快速理解

說io模型前先說一下同步 非同步 阻塞 非阻塞的區分 同步 非同步關注的是訊息通訊機制 阻塞 非阻塞關注的是等待訊息時的狀態 同步 非同步 比如本人去燒一壺水,然後水開之後還是需要本人親自去把水裝在水壺裡這叫同步,假如水開後我不用去裝水,由我提前安排好的人去做叫非同步。阻塞 非阻塞 如果在燒水的過程...

簡單理解io與nio

io是面向流的,而nio是面向緩衝區的 io每次從流中讀取乙個或者多個位元組,直到讀取完所有的位元組,這就意外著它是阻塞式的,當乙個執行緒執行read或者write的時候,這個執行緒是不能夠再去做其他的事情了 nio會讀取資料放到乙個緩衝區裡,這樣可以增加讀取資料的靈活性,可以前後移動讀取資料的位置...

IO與NIO網路程式設計模型

一 bio bolcking io 阻塞分析 阻塞點 1.建立服務埠 serversocket serversocket new serversocket 12345 獲取socket套接字 socket socket serversocket.accept 阻塞等待客戶端連線 2.獲取客戶端輸入流...