web中nio的理解

傳統(tǒng)的bio線程模型是
用戶發(fā)起請求,accept得到一個socket,然后從業(yè)務(wù)線程池取出一個線程去處理該用戶的請求
業(yè)務(wù)線程池線程數(shù) + acceptCount = 最大用戶連接數(shù)
業(yè)務(wù)線程池線程數(shù) = 最大并發(fā)處理請求數(shù)
調(diào)大acceptCount可以提高最大連接數(shù)
如果希望減少線程切換的消耗且連接數(shù)不變,則應(yīng)該降低線程池數(shù),提高acceptCount

nio一般有三個線程池
創(chuàng)建連接線程池
非阻塞io線程池
業(yè)務(wù)線程池
最大連接數(shù)與業(yè)務(wù)線程池線程數(shù)無關(guān),完全在于配置
業(yè)務(wù)線程池線程數(shù)=最大并發(fā)處理請求數(shù)

可見線程模型并非是nio的優(yōu)勢。bio和nio最終其實都是一個用戶對應(yīng)一個線程的。

netty nio零拷貝是java應(yīng)用層的零拷貝
https://stackoverflow.com/questions/20727615/is-nettys-zero-copy-different-from-os-level-zero-copy

另外提一下,socketChannel的write方法,由于系統(tǒng)層面要求內(nèi)存地址是固定的,而java內(nèi)的byte[]是特殊的對象,gc后內(nèi)存地址很可能改變,因此必須使用堆外內(nèi)存。所以對于web應(yīng)用,因為往往都是先轉(zhuǎn)換成java內(nèi)部的byte[]對象,所以必然至少要經(jīng)歷一次往堆外內(nèi)存的拷貝。

可見,線程模型和內(nèi)存拷貝方面,nio并不比bio有優(yōu)勢。
個人認為,web中nio的優(yōu)勢還是在于,可以通過單線程完成多個通道的讀寫。比如在一個http服務(wù)器中,我們通過非阻塞的讀,直到讀完一個完整的http報文(或header),才下發(fā)到工作線程,由servlet去處理。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容