傳統(tǒng)的bio線程模型是
用戶發(fā)起請(qǐng)求续誉,accept得到一個(gè)socket鞍爱,然后從業(yè)務(wù)線程池取出一個(gè)線程去處理該用戶的請(qǐng)求
業(yè)務(wù)線程池線程數(shù) + acceptCount = 最大用戶連接數(shù)
業(yè)務(wù)線程池線程數(shù) = 最大并發(fā)處理請(qǐng)求數(shù)
調(diào)大acceptCount可以提高最大連接數(shù)
如果希望減少線程切換的消耗且連接數(shù)不變,則應(yīng)該降低線程池?cái)?shù)厢钧,提高acceptCount
nio一般有三個(gè)線程池
創(chuàng)建連接線程池
非阻塞io線程池
業(yè)務(wù)線程池
最大連接數(shù)與業(yè)務(wù)線程池線程數(shù)無關(guān)鳞尔,完全在于配置
業(yè)務(wù)線程池線程數(shù)=最大并發(fā)處理請(qǐng)求數(shù)
可見線程模型并非是nio的優(yōu)勢。bio和nio最終其實(shí)都是一個(gè)用戶對(duì)應(yīng)一個(gè)線程的早直。
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[]是特殊的對(duì)象昧旨,gc后內(nèi)存地址很可能改變,因此必須使用堆外內(nèi)存祥得。所以對(duì)于web應(yīng)用兔沃,因?yàn)橥际窍绒D(zhuǎn)換成java內(nèi)部的byte[]對(duì)象,所以必然至少要經(jīng)歷一次往堆外內(nèi)存的拷貝级及。
可見乒疏,線程模型和內(nèi)存拷貝方面,nio并不比bio有優(yōu)勢饮焦。
個(gè)人認(rèn)為怕吴,web中nio的優(yōu)勢還是在于窍侧,可以通過單線程完成多個(gè)通道的讀寫。比如在一個(gè)http服務(wù)器中转绷,我們通過非阻塞的讀伟件,直到讀完一個(gè)完整的http報(bào)文(或header),才下發(fā)到工作線程议经,由servlet去處理斧账。