IO/NIO/BIO的區(qū)別

在學(xué)習(xí)Java I/O類庫時(shí),容易混淆NIO、BIO、AIO這幾個(gè)概念,同時(shí)對(duì)于阻塞和非阻塞、同步和異步的理解也較為晦澀,這篇文章是對(duì)這幾個(gè)概念的一些區(qū)分以及個(gè)人的一些見解。
一、同步阻塞I/O(BIO):
同步阻塞I/O,服務(wù)器實(shí)現(xiàn)模式為一個(gè)連接一個(gè)線程,即客戶端有連接請(qǐng)求時(shí)服務(wù)器就需要啟動(dòng)一個(gè)線程進(jìn)行處理,如果這個(gè)連接不做任何事情會(huì)造成不必要的線程開銷,可以通過線程池機(jī)制來改善。BIO方式適用于連接數(shù)目比較小且固定的架構(gòu),這種方式對(duì)服務(wù)端資源要求比較高,并發(fā)局限于應(yīng)用中,在jdk1.4以前是唯一的io現(xiàn)在,但程序直觀簡(jiǎn)單易理解
二、同步非阻塞I/O(NIO):
同步非阻塞I/O,服務(wù)器實(shí)現(xiàn)模式為一個(gè)請(qǐng)求一個(gè)線程,即客戶端發(fā)送的連接請(qǐng)求都會(huì)注冊(cè)到多路復(fù)用器上,多路復(fù)用器輪詢到連接有IO請(qǐng)求時(shí)才啟動(dòng)一個(gè)線程進(jìn)行處理。NIO方式適用于連接數(shù)目多且連接比較短(輕操作)的架構(gòu),比如聊天服務(wù)器,并發(fā)局限于應(yīng)用中,編程比較復(fù)雜,jdk1,4開始支持
三、異步非阻塞I/O(AIO):
異步非阻塞I/O,服務(wù)器實(shí)現(xiàn)模式為一個(gè)有效請(qǐng)求一個(gè)線程,客戶端的IO請(qǐng)求都是由操作系統(tǒng)先完成了再通知服務(wù)器用其啟動(dòng)線程進(jìn)行處理。AIO方式適用于連接數(shù)目多且連接比較長(zhǎng)(重操作)的架構(gòu),比如相冊(cè)服務(wù)器,充分調(diào)用OS參與并發(fā)操作,編程比較復(fù)雜,jdk1.7開始支持。
四、IO與NIO區(qū)別:
IO面向流,NIO面向緩沖區(qū)
IO的各種流是阻塞的,NIO是非阻塞模式
Java NIO的選擇允許一個(gè)單獨(dú)的線程來監(jiān)視多個(gè)輸入通道,可以注冊(cè)多個(gè)通道使用一個(gè)選擇器,然后使用一個(gè)單獨(dú)的線程來“選擇”通道:這些通道里已經(jīng)有可以處理的輸入或選擇已準(zhǔn)備寫入的通道。這種選擇機(jī)制,使得一個(gè)單獨(dú)的線程很容易來管理多個(gè)通道
五、同步與異步的區(qū)別:
同步:發(fā)送一個(gè)請(qǐng)求,等待返回,再發(fā)送下一個(gè)請(qǐng)求,同步可以避免出現(xiàn)死鎖,臟讀的發(fā)生
異步:發(fā)送一個(gè)請(qǐng)求,不等待返回,隨時(shí)可以再發(fā)送下一個(gè)請(qǐng)求,可以提高效率,保證并發(fā)
同步異步關(guān)注點(diǎn)在于消息通信機(jī)制,
阻塞與非阻塞關(guān)注的是程序在等待調(diào)用結(jié)果時(shí)(消息、返回值)的狀態(tài):
阻塞調(diào)用是指調(diào)用結(jié)果返回之前,當(dāng)前線程會(huì)被掛起。調(diào)用線程只有在得到結(jié)果之后才會(huì)返回。
非阻塞調(diào)用指在不能立刻得到結(jié)果之前,該調(diào)用不會(huì)阻塞當(dāng)前線程
不同層次:
CPU層次:操作系統(tǒng)進(jìn)行IO或任務(wù)調(diào)度層次,現(xiàn)代操作系統(tǒng)通常使用異步非阻塞方式進(jìn)行IO(有少部分IO可能會(huì)使用同步非阻塞),即發(fā)出IO請(qǐng)求后,并不等待IO操作完成,而是繼續(xù)執(zhí)行接下來的指令(非阻塞),IO操作和CPU指令互不干擾(異步),最后通過中斷的方式通知IO操作的完成結(jié)果。
線程層次:操作系統(tǒng)調(diào)度單元的層次,操作系統(tǒng)為了減輕程序員的思考負(fù)擔(dān),將底層的異步非阻塞的IO方式進(jìn)行封裝,把相關(guān)系統(tǒng)調(diào)用(如read和write)以同步的方式展現(xiàn)出來,然而同步阻塞IO會(huì)使線程掛起,同步非阻塞IO會(huì)消耗CPU資源在輪詢上,3個(gè)解決方法;
多線程(同步阻塞)
IO多路復(fù)用(select、poll、epoll)
直接暴露出異步的IO接口,kernel-aio和IOCP(異步非阻塞)
Linux IO模型:
阻塞/非阻塞:等待I/O完成的方式,阻塞要求用戶程序停止執(zhí)行,直到IO完成,而非阻塞在IO完成之前還可以繼續(xù)執(zhí)行
同步/異步:獲知IO完成的方式,同步需要時(shí)刻關(guān)心IO是否完成,異步無需主動(dòng)關(guān)心,在IO完成時(shí)它會(huì)收到通知
