Java IO 分類
Java BIO: 同步并阻塞境肾,服務(wù)器實(shí)現(xiàn)模式為一個(gè)連接一個(gè)線程,即客戶端有連接請(qǐng)求時(shí)服務(wù)器端就需要啟動(dòng)一個(gè)線程進(jìn)行處理西采,如果這個(gè)連接不做任何事情會(huì)造成不必要的線程開銷越庇,當(dāng)然可以通過線程池機(jī)制改善。
Java NIO: 同步非阻塞猜丹,服務(wù)器實(shí)現(xiàn)模式為一個(gè)請(qǐng)求一個(gè)線程,即當(dāng)一個(gè)連接創(chuàng)建后硅卢,不需要對(duì)應(yīng)一個(gè)線程射窒,這個(gè)連接會(huì)被注冊(cè)到多路復(fù)用器上面妖混,所以所有的連接只需要一個(gè)線程就可以搞定,當(dāng)這個(gè)線程中的多路復(fù)用器進(jìn)行輪詢的時(shí)候轮洋,發(fā)現(xiàn)連接上有請(qǐng)求的話,才開啟一個(gè)線程進(jìn)行處理抬旺,也就是一個(gè)請(qǐng)求一個(gè)線程模式弊予。BIO與NIO一個(gè)比較重要的不同,是我們使用BIO的時(shí)候往往會(huì)引入多線程开财,每個(gè)連接一個(gè)單獨(dú)的線程汉柒;而NIO則是使用單線程或者只使用少量的多線程,每個(gè)連接共用一個(gè)線程责鳍。
Java AIO(NIO.2): 異步非阻塞碾褂,服務(wù)器實(shí)現(xiàn)模式為一個(gè)有效請(qǐng)求一個(gè)線程,客戶端的I/O請(qǐng)求都是由OS先完成了再通知服務(wù)器應(yīng)用去啟動(dòng)線程進(jìn)行處理历葛。
名詞解釋
同步:指的是用戶進(jìn)程觸發(fā)IO操作需要等待或者輪詢的去查看IO操作執(zhí)行完成才能執(zhí)行其他操作.這種方式性能比較差正塌,只有一些對(duì)數(shù)據(jù)安全性要求比較高的場景中才會(huì)使用.
異步:異步是指用戶進(jìn)程觸發(fā)IO操作以后便開始做自己的事情,而當(dāng)IO操作已經(jīng)完成的時(shí)候會(huì)得到IO完成的通知(異步的特點(diǎn)就是通知)
阻塞:所謂阻塞方式的意思是指, 當(dāng)試圖對(duì)該文件描述符進(jìn)行讀寫時(shí), 如果當(dāng)時(shí)沒有東西可讀,或者暫時(shí)不可寫, 程序就進(jìn)入等待 狀態(tài), 直到有東西可讀或者可寫為止
非阻塞:非阻塞狀態(tài)下, 如果沒有東西可讀, 或者不可寫, 讀寫函數(shù)馬上返回, 而不會(huì)等待
BIO恤溶、NIO乓诽、AIO適用場景分析
BIO方式適用于連接數(shù)目比較小且固定的架構(gòu),這種方式對(duì)服務(wù)器資源要求比較高咒程,并發(fā)局限于應(yīng)用中鸠天,JDK1.4以前的唯一選擇,但程序直觀簡單易理解帐姻。
NIO方式適用于連接數(shù)目多且連接比較短(輕操作)的架構(gòu)稠集,比如聊天服務(wù)器,并發(fā)局限于應(yīng)用中饥瓷,編程比較復(fù)雜剥纷,JDK1.4開始支持。
AIO方式使用于連接數(shù)目多且連接比較長(重操作)的架構(gòu)扛伍,比如相冊(cè)服務(wù)器筷畦,充分調(diào)用OS參與并發(fā)操作,編程比較復(fù)雜刺洒,JDK7開始支持鳖宾。
Java NIO和IO的主要區(qū)別
面向流與面向緩沖. Java NIO和IO之間第一個(gè)最大的區(qū)別是,IO是面向流的逆航,NIO是面向緩沖區(qū)的鼎文。Java IO面向流意味著每次從流中讀一個(gè)或多個(gè)字節(jié),直至讀取所有字節(jié)因俐,它們沒有被緩存在任何地方拇惋。此外周偎,它不能前后移動(dòng)流中的數(shù)據(jù)。如果需要前后移動(dòng)從流中讀取的數(shù)據(jù)撑帖,需要先將它緩存到一個(gè)緩沖區(qū)蓉坎。 Java NIO的緩沖導(dǎo)向方法略有不同。數(shù)據(jù)讀取到一個(gè)它稍后處理的緩沖區(qū)胡嘿,需要時(shí)可在緩沖區(qū)中前后移動(dòng)蛉艾。這就增加了處理過程中的靈活性。
阻塞與非阻塞IO Java IO的各種流是阻塞的衷敌。這意味著勿侯,當(dāng)一個(gè)線程調(diào)用read() 或 write()時(shí),該線程被阻塞缴罗,直到有一些數(shù)據(jù)被讀取助琐,或數(shù)據(jù)完全寫入。該線程在此期間不能再干任何事情了面氓。 Java NIO的非阻塞模式兵钮,使一個(gè)線程從某通道發(fā)送請(qǐng)求讀取數(shù)據(jù),但是它僅能得到目前可用的數(shù)據(jù)侧但,如果目前沒有數(shù)據(jù)可用時(shí)矢空,該線程可以繼續(xù)做其他的事情。 非阻塞寫也是如此禀横。一個(gè)線程請(qǐng)求寫入一些數(shù)據(jù)到某通道屁药,但不需要等待它完全寫入,這個(gè)線程同時(shí)可以去做別的事情柏锄。線程通常將非阻塞IO的空閑時(shí)間用于在其它通道上執(zhí)行IO操作酿箭,所以一個(gè)單獨(dú)的線程現(xiàn)在可以管理多個(gè)輸入和輸出通道(channel)。
選擇器(Selectors) Java NIO的選擇器允許一個(gè)單獨(dú)的線程來監(jiān)視多個(gè)輸入通道趾娃,你可以注冊(cè)多個(gè)通道使用一個(gè)選擇器缭嫡,然后使用一個(gè)單獨(dú)的線程來“選擇”通道:這些通道里已經(jīng)有可以處理的輸入,或者選擇已準(zhǔn)備寫入的通道抬闷。這種選擇機(jī)制妇蛀,使得一個(gè)單獨(dú)的線程很容易來管理多個(gè)通道。