當前位置:
首頁 > 知識 > 談談傳統BIO網路編程模型的局限性與NIO

談談傳統BIO網路編程模型的局限性與NIO

先來看看我們的server端:

創建一個serversocket,進行監聽,每來一個客戶端,就啟動一個新啟動為其服務:

private void createListenSocket() {

//如果創建監聽socket的時候發生異常,將會隔WAIT_TIME毫秒重試,直到成功

while (true){

try {

serverSocket = new ServerSocket(LISTEN_PORT);

Log.info(創建監聽socket成功,正在監聽...);

break;

} catch (IOException e) {

Log.error(創建監聽socket失敗,原因: e.getMessage() WAIT_TIME ms後重建);

ThreadUtils.sleep(WAIT_TIME);

}

}

}

private void listen() throws IOException {

Socket socket = null;

//啟動一個死循環來監聽連接本伺服器的socket

while ((socket = server.accept()) != null) {

// 來訪客戶記錄到伺服器:

Destination destination = new Destination();

destination.setSocket(socket);

server.newDestination(destination);

//啟動一條子線程來處理連接本伺服器的socket消息收發

new SubListenThread(destination,server).start();

}

}

以上代碼來自我半年前編寫的一個遠控程序服務端。在這個模型當中,服務端線程與客戶端線程是1:1的關係,也就是說有多少個客戶端,服務端就得創建多少個線程。

在java當中,創建線程的代價是很大的。如果有幾千個客戶端,這個程序是撐不住的。

那麼像旺旺這種在線量可以達到幾百萬的應用,在單個機器上,勢必要用一種比BIO更好的編程模型來實現。

那麼NIO就可以解決這種應用場景。

關於NIO的教程,網上有非常多的詳細教程,在這裡就不贅述。就簡單說說NIO編程模型:

首先,我們有幾個基本概念:

1.channel 大家可以把它想像成stream,只不過我們可以通過channel進行雙工通信,也就是能讀又能寫。

2.buffer 可以看做是一段緩存,我們能通過這麼一段緩存對channel進行讀寫。

3.selector 中文直接翻譯過來就是選擇器,因為在NIO當中,我們不通過傳統的一個線程處理一個客戶端,而是通過輪詢的方式知道哪些客戶端可讀、可連接,從而實現1:n的模型。

那麼NIO的編程模型如下:

通過一個selector,客戶端會連接到這個selector,我們可以通過一個死循環不斷地輪詢selector有哪些客戶端,然後一旦監聽到可讀或者可連接事件,我們就進行相應的業務邏輯處理,該讀讀,該寫寫。

以下為一個簡單多人聊天室部分源碼:

看起來還是很複雜的,至少比傳統的BIO通信模型複雜。

使用原生的nio api進行編程很難,而且這玩意還有bug,據說在1.8以上版本仍存在空輪詢BUG,會讓CPU飆到100%。

所以說,如果可以的話,盡量使用一些第三方框架,比如netty。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 千鋒JAVA開發學院 的精彩文章:

剖析Hadoop和Spark的Shuffle過程差異
30秒了解Excel的前世今生

TAG:千鋒JAVA開發學院 |