傳統的io(阻塞式)
客戶端發送請求給服務端以后
服務端不能確定客戶端發送來的請求
此時線程就會處於一個阻塞狀態
客戶端發送讀寫請求,服務端不能確定數據是否有效
此時的線程一直處於阻塞狀態
等待有正確的數據之后才會立即執行
此時任何操作都做不了
如果有大量請求
前方的阻塞
后方的請求也會阻塞
都會進入一個隊列
解決方法:多線程
此時的問題:服務器的線程也是有限的
此時的cpu利用率沒有完全的合理利用
傳統的 IO 流都是阻塞式的。也就是說,當一個線程調用 read() 或 write()
時,該線程被阻塞,直到有一些數據被讀取或寫入,該線程在此期間不
能執行其他任務。因此,在完成網絡通信進行 IO 操作時,由於線程會
阻塞,所以服務器端必須為每個客戶端都提供一個獨立的線程進行處理,
當服務器端需要處理大量客戶端時,性能急劇下降。
NIO(非阻塞式)
提出一個核心的組件:選擇器
選擇器:會把每一個通道都注冊到選擇器上
監控這些通道的IO狀況(讀寫、連接、接收數據....)
在任務完全准備好了以后
在把任務分配給服務端的一個或多個線程上
如果沒准備就緒,就不會將任務分配給服務器上
此時可以進一步利用cpu的資源
Java NIO 是非阻塞模式的。當線程從某通道進行讀寫數據時,若沒有數
據可用時,該線程可以進行其他任務。線程通常將非阻塞 IO 的空閑時
間用於在其他通道上執行 IO 操作,所以單獨的線程可以管理多個輸入
和輸出通道。因此,NIO 可以讓服務器端使用一個或有限幾個線程來同
時處理連接到服務器端的所有客戶端。