1.前言緩存
在看書的時候,看到了Nio。這時候我去學習了Nio的相關知識,以及和io的區別,這兩個什麼時候該使用。學習
2.Nio和Io的區別線程
上老圖:3d
由圖可知,Nio是面向緩衝的,Io是面向流的blog
2.1讀取:input
對於Io是經過流每次讀取一個字節,寫也是每次寫入一個字節篩選出 。若是想再讀一次,或者從中間讀,就必須先把流中的數據保存一份。對於Nio必須先將inputstream等流先寫到緩存區(buffer)。這個時候你能夠任意的使用這個buffer,以及從任意位置開始讀取。it
2.2 阻塞與非阻塞io
Java的Io是阻塞的,當線程調用read()或者write()方法時,該線程會被阻塞,直到這個io操做完成爲止。只有完成這個操做,這個線程才能作其餘的事情。stream
Java的NIo想了一個好的方法來作到非阻塞。他用到了selector,channel和buffer。當一個線程到通道channel中請求讀取數據的時候,僅能讀取到目前channel寫入的數據。由於是非阻塞的緣由,客戶端在讀取的時候要本身判斷是否已經所有寫入完成。同時,若是沒有數據,不會阻塞,客戶端會立馬接收到null,客戶端線程能夠去作其餘的事情,而不用等待。select
Nio就是使用少數的線程來做爲selector,設置爲非阻塞,而後指定端口,這些線程就能夠接受大量的客戶端鏈接來處理流。每當有一個客戶端鏈接的時候,就會有一個channel註冊到selector上,他們會根據一個key來本身創建聯繫,直到流寫入完成,key失效爲止。
2.3 線程鏈接數
總而言之,
當有大量鏈接,可是每一個鏈接傳輸的流比較小的時候,適合使用NIo;
當只有少許鏈接,可是一個鏈接會有大量數據傳輸的時候,適合使用Io(一個鏈接,一個線程);
3 Nio詳細
NIo是經過一個無限循環來不斷輪詢selector是否有註冊上來的channel。同時每一個註冊上來的channel都是有不一樣的狀態,分別爲connection,accept,read,write。每經過一個狀態,會從新往selector從新註冊一個channel,這也是爲何客戶端在讀取數據的時候,須要作是否已經寫入完畢的判斷。一旦selector拿到數據,他會返回全部和他創建鏈接的channel的key,並經過這個key和狀態作相應的操做。
4 之後
Nio還在初步學習階段,後續再完善了!
如有錯誤,懇請指正,萬分感謝!!!