我們知道在生活中,等人是一件很煩的事,同樣,在程式碼中等待(阻塞)不僅影響效能,降低效率,而且還極大的浪費資源!
在JAVA4之前,JAVA的IO模型為blocking IO(BIO),即阻塞IO,在連線建立後,如果沒有資料傳輸就會一直處於阻塞狀態,這時候從執行緒來看就處於休眠狀態,從CPU來看就是處於停滯狀態,極大的浪費CPU的計算能力,如果以這個模型開發應用伺服器,則因為大量執行緒阻塞,佔用記憶體資源大,導致有效連線數很低,比如說一個JAVA執行緒佔用1m的記憶體,那麼一個8G的記憶體頂多支援8000個連線,這對動輒百萬玩家線上遊戲等長連線模型,肯定是不能處理的!
JAVA在4版本,引進了NIO(Non-Blocking IO),即非阻塞IO,如何才能做到非阻塞呢?
如果發起了幾千個連線,但是隻有幾個連線需要資料傳輸,使用BIO需要維持幾千個連線,但是NIO是事件觸發機制,啟動一個執行緒不斷的對連線進行迴圈,如果有需要資料傳輸的就進行處理,如果沒有,繼續迴圈,這樣只需要一個執行緒就能維持幾千的連線,記憶體消耗相比BIO十分的低!
既然NIO如此高效,那麼怎麼學習JAVA NIO呢?
1,明白NIO原理:BIO通常以位元組流或者字元流進行資料傳輸,而NIO使用bufffer緩衝,channel管道,selector選擇器進行核心實現!
channel負責資料的傳輸,有不同的管道型別,比如檔案管道FileChannel,一般從流(輸入或者輸出)獲取到管道(getChannel()方法)!
buffer作為資料的緩衝,能一次性大量的傳輸資料,避免了單個位元組寫資料的低效率,通常buffer有容量capacity,資料總量limit,指向專屬位置position,記錄上次讀寫位置的標誌mark四個指標,對應相應的同名函式作為呼叫方法,實現對緩衝中資料指標的獲取,再使用put,get方法從緩衝區設定或者獲取資料!
掌握NIO相應的API!
2,學習netty:netty作為JAVA NIO的最流行框架,其思想被廣泛應用在諸如nginx,redis等著名的框架中,netty作為一個同步非阻塞IO模型,透過IO多路複用將需要處理的事件放入一個FIFO佇列,然後逐一處理,使用linux中的epoll模型,避免selector模型中對所有連線的輪詢,效能更加的高效!
學習netty將會開啟一個高併發,高效能的大門,是網路IO不可不學的模型!
3,自己練:仿照netty實現一個自己的io多路複用框架,或者高效能RPC框架,加深對nio的理解!
總的來說,NIO在對長連線方式的服務中,有著BIO難以企及的優秀效能,但是程式設計難度提升不少,所有可以根據需求做出最優的選擇,NIO就說到這,改天說下AIO,更多的技術分享,敬請關注。。。
我們知道在生活中,等人是一件很煩的事,同樣,在程式碼中等待(阻塞)不僅影響效能,降低效率,而且還極大的浪費資源!
在JAVA4之前,JAVA的IO模型為blocking IO(BIO),即阻塞IO,在連線建立後,如果沒有資料傳輸就會一直處於阻塞狀態,這時候從執行緒來看就處於休眠狀態,從CPU來看就是處於停滯狀態,極大的浪費CPU的計算能力,如果以這個模型開發應用伺服器,則因為大量執行緒阻塞,佔用記憶體資源大,導致有效連線數很低,比如說一個JAVA執行緒佔用1m的記憶體,那麼一個8G的記憶體頂多支援8000個連線,這對動輒百萬玩家線上遊戲等長連線模型,肯定是不能處理的!
JAVA在4版本,引進了NIO(Non-Blocking IO),即非阻塞IO,如何才能做到非阻塞呢?
如果發起了幾千個連線,但是隻有幾個連線需要資料傳輸,使用BIO需要維持幾千個連線,但是NIO是事件觸發機制,啟動一個執行緒不斷的對連線進行迴圈,如果有需要資料傳輸的就進行處理,如果沒有,繼續迴圈,這樣只需要一個執行緒就能維持幾千的連線,記憶體消耗相比BIO十分的低!
既然NIO如此高效,那麼怎麼學習JAVA NIO呢?
1,明白NIO原理:BIO通常以位元組流或者字元流進行資料傳輸,而NIO使用bufffer緩衝,channel管道,selector選擇器進行核心實現!
channel負責資料的傳輸,有不同的管道型別,比如檔案管道FileChannel,一般從流(輸入或者輸出)獲取到管道(getChannel()方法)!
buffer作為資料的緩衝,能一次性大量的傳輸資料,避免了單個位元組寫資料的低效率,通常buffer有容量capacity,資料總量limit,指向專屬位置position,記錄上次讀寫位置的標誌mark四個指標,對應相應的同名函式作為呼叫方法,實現對緩衝中資料指標的獲取,再使用put,get方法從緩衝區設定或者獲取資料!
掌握NIO相應的API!
2,學習netty:netty作為JAVA NIO的最流行框架,其思想被廣泛應用在諸如nginx,redis等著名的框架中,netty作為一個同步非阻塞IO模型,透過IO多路複用將需要處理的事件放入一個FIFO佇列,然後逐一處理,使用linux中的epoll模型,避免selector模型中對所有連線的輪詢,效能更加的高效!
學習netty將會開啟一個高併發,高效能的大門,是網路IO不可不學的模型!
3,自己練:仿照netty實現一個自己的io多路複用框架,或者高效能RPC框架,加深對nio的理解!
總的來說,NIO在對長連線方式的服務中,有著BIO難以企及的優秀效能,但是程式設計難度提升不少,所有可以根據需求做出最優的選擇,NIO就說到這,改天說下AIO,更多的技術分享,敬請關注。。。