BIO:同步阻塞式IO,服務器實現模式爲一個鏈接一個線程,即客戶端有鏈接請求時服務器端就須要啓動一個線程進行處理,若是這個鏈接不作任何事情會形成沒必要要的線程開銷,固然能夠經過線程池機制改善。
NIO:同步非阻塞式IO,服務器實現模式爲一個請求一個線程,即客戶端發送的鏈接請求都會註冊到多路複用器上,多路複用器輪詢到鏈接有I/O請求時才啓動一個線程進行處理。 html
BIO
同步阻塞式IO,相信每個學習過操做系統網絡編程或者任何語言的網絡編程的人都很熟悉,在while循環中服務端會調用accept方法等待接收客戶端的鏈接請求,一旦接收到一個鏈接請求,就能夠創建通訊套接字在這個通訊套接字上進行讀寫操做,此時不能再接收其餘客戶端鏈接請求,只能等待同當前鏈接的客戶端的操做執行完成。
若是BIO要可以同時處理多個客戶端請求,就必須使用多線程,即每次accept阻塞等待來自客戶端請求,一旦受到鏈接請求就創建通訊套接字同時開啓一個新的線程來處理這個套接字的數據讀寫請求,而後馬上又繼續accept等待其餘客戶端鏈接請求,即爲每個客戶端鏈接請求都建立一個線程來單獨處理,大概原理圖就像這樣:
java
雖然此時服務器具有了高併發能力,即可以同時處理多個客戶端請求了,可是卻帶來了一個問題,隨着開啓的線程數目增多,將會消耗過多的內存資源,致使服務器變慢甚至崩潰,NIO能夠必定程度解決這個問題。數據庫
NIO
同步非阻塞式IO,關鍵是採用了事件驅動的思想來實現了一個多路轉換器。
NIO與BIO最大的區別就是只須要開啓一個線程就能夠處理來自多個客戶端的IO事件,這是怎麼作到的呢?
就是多路複用器,能夠監聽來自多個客戶端的IO事件:
A. 若服務端監聽到客戶端鏈接請求,便爲其創建通訊套接字(java中就是通道),而後返回繼續監聽,若同時有多個客戶端鏈接請求到來也能夠所有收到,依次爲它們都創建通訊套接字。
B. 若服務端監聽到來自已經建立了通訊套接字的客戶端發送來的數據,就會調用對應接口處理接收到的數據,若同時有多個客戶端發來數據也能夠依次進行處理。
C. 監聽多個客戶端的鏈接請求和接收數據請求同時還能監聽本身時候有數據要發送。
總之就是在一個線程中就能夠調用多路複用接口(java中是select)阻塞同時監聽來自多個客戶端的IO請求,一旦有收到IO請求就調用對應函數處理。
一旦有請求到來(不論是幾個同時到仍是隻有一個到),都會調用對應IO處理函數處理,因此:編程
(1)NIO適合處理鏈接數目特別多,可是鏈接比較短(輕操做)的場景,Jetty,Mina,ZooKeeper等都是基於java nio實現。服務器
(2)BIO方式適用於鏈接數目比較小且固定的場景,這種方式對服務器資源要求比較高,併發侷限於應用中。網絡
同步與異步多線程
在設計到 IO 處理時一般都會遇到一個是同步仍是異步的處理方式的選擇問題。由於同步與異步的 I/O 處理方式對調用者的影響很大,在數據庫產品中都會遇到這個問題。由於 I/O 操做一般是一個很是耗時的操做,在一個任務序列中 I/O 一般都是性能瓶頸。可是同步與異步的處理方式對程序的可靠性影響很是大,同步可以保證程序的可靠性,而異步能夠提高程序的性能,必須在可靠性和性能之間作個平衡,沒有完美的解決辦法。併發
阻塞與非阻塞app
阻塞和非阻塞關注的是程序在等待調用結果(消息,返回值)時的狀態異步
阻塞與非阻塞主要是從 CPU 的消耗上來講的,阻塞就是 CPU 停下來等待一個操做完成 CPU 才接着完成其它的事。非阻塞就是在這個操做在執行時 CPU 去幹其它別的事,等這個操做完成時,CPU 再接着完成後續的操做。雖然表面上看非阻塞的方式能夠明顯的提升 CPU 的利用率,可是也帶了另一種後果就是系統的線程切換增長。增長的 CPU 使用時間能不能補償系統的切換成本須要好好評估。
組合的方式能夠由四種,分別是:同步阻塞、同步非阻塞、異步阻塞、異步非阻塞,這四種方式都對 I/O 性能有影響。雖然異步和非阻塞可以提高 I/O 的性能,可是也會帶來一些額外的性能成本,例如會增長線程數量從而增長 CPU 的消耗,同時也會致使程序設計的複雜度上升。若是設計的不合理的話反而會致使性能降低。
參考連接:http://www.cnblogs.com/zedosu/p/6666984.html
同步與異步
所謂同步就是一個任務的完成須要依賴另一個任務時,只有等待被依賴的任務完成後,依賴的任務才能算完成,這是一種可靠的任務序列。要麼成功都成功,失敗都失敗,兩個任務的狀態能夠保持一致。而異步是不須要等待被依賴的任務完成,只是通知被依賴的任務要完成什麼工做,依賴的任務也當即執行,只要本身完成了整個任務就算完成了。至於被依賴的任務最終是否真正完成,依賴它的任務沒法肯定,因此它是不可靠的任務序列。咱們能夠用打電話和發短信來很好的比喻同步與異步操做。
在設計到 IO 處理時一般都會遇到一個是同步仍是異步的處理方式的選擇問題。由於同步與異步的 I/O 處理方式對調用者的影響很大,在數據庫產品中都會遇到這個問題。由於 I/O 操做一般是一個很是耗時的操做,在一個任務序列中 I/O 一般都是性能瓶頸。可是同步與異步的處理方式對程序的可靠性影響很是大,同步可以保證程序的可靠性,而異步能夠提高程序的性能,必須在可靠性和性能之間作個平衡,沒有完美的解決辦法。
阻塞與非阻塞
阻塞與非阻塞主要是從 CPU 的消耗上來講的,阻塞就是 CPU 停下來等待一個慢的操做完成 CPU 才接着完成其它的事。非阻塞就是在這個慢的操做在執行時 CPU 去幹其它別的事,等這個慢的操做完成時,CPU 再接着完成後續的操做。雖然表面上看非阻塞的方式能夠明顯的提升 CPU 的利用率,可是也帶了另一種後果就是系統的線程切換增長。增長的 CPU 使用時間能不能補償系統的切換成本須要好好評估。
兩種的方式的組合
組合的方式能夠由四種,分別是:同步阻塞、同步非阻塞、異步阻塞、異步非阻塞,這四種方式都對 I/O 性能有影響。下面給出分析,並有一些經常使用的設計用例參考。