IO、NIO、AIO 内部原理分析
相關(guān)文章
NIO 之 Selector實(shí)現(xiàn)原理
NIO 之 Channel實(shí)現(xiàn)原理
NIO 之 ByteBuffer實(shí)現(xiàn)原理
阻塞IO
所有的讀寫IO都是阻塞操作。
多路復(fù)用模型
select/poll
從程序的角度解釋:
將 channel 注冊(cè)到 seletor 上,通過輪詢channel是否就緒,將就緒的channel返回。epoll
將 channel 注冊(cè)到 selector 上,基于回調(diào)的方式(類似監(jiān)聽者模式),告知selector哪些 channel 已經(jīng)就緒,然后將就緒的 channel 返回。
select/poll 和 epoll 性能分析
對(duì)比 select/poll 和 epoll 我們發(fā)現(xiàn)epoll效率更高。
如果 select/poll 中注冊(cè)了大量的 channel,就要不停的輪詢每個(gè)channel,來判斷那些channel已經(jīng)就緒。而 epoll 則不需要輪詢。
jdk1.4 是使用的 select/poll 模型
jdk1.5 以后把select/poll 改為了epoll模型
異步 I/O
只需要通知內(nèi)核要執(zhí)行什么操作,內(nèi)核執(zhí)行完成后通知你已經(jīng)執(zhí)行完成。
下面分析下 阻塞I/O、NIO、AIO的數(shù)據(jù)處理流程
阻塞I/O 數(shù)據(jù)處理流程
從程序調(diào)用Socket.getInputStream()方法開始一直阻塞到程序有可讀數(shù)據(jù)。
阻塞期間程序不能做任何操作。由于網(wǎng)絡(luò)的傳輸效率問題,程序基本上都是在等待網(wǎng)絡(luò)數(shù)據(jù)傳輸,因此 阻塞I/O 效率很低。
如果客戶端有多個(gè)用戶同時(shí)訪問服務(wù)器,我們一般會(huì)開啟多線程進(jìn)行處理,客戶端的請(qǐng)求。如下圖:
客戶端請(qǐng)求和服務(wù)器線程是一對(duì)一進(jìn)行處理的,大量用戶同時(shí)訪問會(huì)造成服務(wù)器上創(chuàng)建大量的線程(線程上下文切換問題),可能導(dǎo)致服務(wù)器崩潰。
一般我們會(huì)采用線程池進(jìn)行處理請(qǐng)求。
2. NIO 數(shù)據(jù)處理流程
程序需要調(diào)用Seletor.select()方法,阻塞獲取就緒的channel。然后從channel中讀取數(shù)據(jù)做響應(yīng)的處理。這樣一個(gè)線程就可以處理多個(gè)請(qǐng)求,程序只需要處理已經(jīng)就行的channel就ok了。
3.AIO 數(shù)據(jù)處理流程
程序調(diào)用AIO的accept方法并傳入Completionhandler,該方法是非阻塞方法。
等數(shù)據(jù)準(zhǔn)備完成后回調(diào)Completionhandler處理響應(yīng)操作。
程序只需要把具體的操作告知AIO就可以了,具體操作AIO來幫助你來操作。
NIO 和 AIO 性能上對(duì)比
AIO在性能上相對(duì)于NIO沒有本質(zhì)的提升。
AIO只是幫助你從內(nèi)核中將數(shù)據(jù)復(fù)制到用戶空間中,并調(diào)用你傳入的回調(diào)方法。
NIO 是需要程序自己從內(nèi)核中將數(shù)據(jù)復(fù)制到用戶空間中,并需要程序自己調(diào)用相應(yīng)的處理邏輯。
本人簡書blog地址:http://www.jianshu.com/u/1f0067e24ff8????
點(diǎn)擊這里快速進(jìn)入簡書
GIT地址:http://git.oschina.net/brucekankan/
點(diǎn)擊這里快速進(jìn)入GIT
總結(jié)
以上是生活随笔為你收集整理的IO、NIO、AIO 内部原理分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NIO 之 Selector实现原理
- 下一篇: zzuliOJ 2536: 绿绿学姐与A