目錄:
-
1轿腺、阻塞IO(Block IO)與非阻塞IO(Non-Block IO)
-
1.1两嘴、阻塞IO(Block IO)與非阻塞IO(Non-Block IO)區(qū)別
-
1.2、阻塞IO(Block IO)與非阻塞IO(Non-Block IO)類比
-
-
2族壳、同步IO(Syn IO)與異步IO(Asyn IO)
-
2.1憔辫、同步IO(Syn IO)和異步IO(Asyn IO)的對比
-
2.2、同步IO和異步IO還是比較抽象仿荆,繼續(xù)類比
-
2.2贰您、同步IO和異步IO 類比貨車?yán)?/h6>
-
-
3、BIO拢操、NIO锦亦、AIO
-
3.1、BIO令境、NIO之間的對比
-
3.2杠园、對比之面向流與面向緩沖區(qū)
-
3.3、對比之阻塞與非阻塞
-
3.4舔庶、selector選擇器問世
-
3.5抛蚁、NIO 和 BIO 讀取磁盤數(shù)據(jù)的對比
-
3.6玲昧、BIO、NIO篮绿、AIO應(yīng)用場景
-
-
4、面試常見問題
-
4.1吕漂、流按照傳輸?shù)姆较蛟趺捶诸悾?/h6>
-
4.2亲配、流按照傳輸?shù)膯挝辉趺捶诸悾糠殖赡膬煞N流,并且他們的父類叫什么惶凝?說一下常用的IO流吼虎?
-
4.3、流按實現(xiàn)功能怎么分苍鲜?
-
4.4思灰、FileInputStream和FileOutputStream 與 BufferedInputStream 和 BufferedOutputStream區(qū)別?
-
4.5混滔、flush() 方法的作用洒疚?
-
1、阻塞IO(Block)與非阻塞IO(Non-Block)
1.1坯屿、阻塞IO(Block)與非阻塞IO(Non-Block)區(qū)別:
阻塞和非阻塞是服務(wù)端進程(線程)
在訪問數(shù)據(jù)的時候油湖,數(shù)據(jù)是否準(zhǔn)備就緒的一種處理方式:
- 阻塞(Block):需要等待
緩沖區(qū)
中的數(shù)據(jù)準(zhǔn)備好過后才處理其他的事情,否則一直等待
在那里领跛。- eg:SeverSocket 中的accept() 乏德。
- 非阻塞(Non-Block):進程訪問數(shù)據(jù)緩沖區(qū)的時候,如果數(shù)據(jù)沒有準(zhǔn)備好則直接返回吠昭,
不會等待
喊括。如果數(shù)據(jù)已經(jīng)準(zhǔn)備好,也直接返回矢棚。- nio 中的Selector 郑什。
1.2、阻塞IO(Block IO)與非阻塞IO(Non-Block IO) 圖解:
2幻妓、同步IO (Syn IO)與異步IO (Asyn IO)
2.1蹦误、同步IO(Syn IO)和異步IO(Asyn IO)的對比:
同步和異步都是基于服務(wù)端
處理請求采用的方式:
- eg:
- 同步(Synchronization):client發(fā)出請求到服務(wù)端,無論服務(wù)端是否阻塞以及其他情況肉津,只要
服務(wù)端同步返回結(jié)果
强胰,就認(rèn)定是同步。 - 異步(Asynchronous):client發(fā)出請求到服務(wù)端妹沙,同步返回值中沒有結(jié)果偶洋,Client只需要
等待通知
,收到通知后才能拉取結(jié)果距糖,就是異步玄窝。
- 同步(Synchronization):client發(fā)出請求到服務(wù)端,無論服務(wù)端是否阻塞以及其他情況肉津,只要
2.2牵寺、同步IO和異步IO還是比較抽象的,繼續(xù)類比:
- 同步IO恩脂,可以類比客戶端與服務(wù)端通信方式采用RPC方式帽氓,同步給返回結(jié)果。
- 異步IO俩块,可以類比客戶端與服務(wù)端通信方式采用MQ+RPC方式黎休,異步給客戶端一個通知,Client端再通過RPC同步返回結(jié)果玉凯。
2.3势腮、同步IO和異步IO 類比生活中貨車?yán)洠?/h6>
同步IO
異步IO
3、BIO漫仆、NIO捎拯、AIO
3.1、Java BIO(Block IO)和 NIO(Non-Block IO)之間的主要差別異:
IO模型 | BIO | NIO |
---|---|---|
通信 | 面向流 | 面向緩沖區(qū)(多路復(fù)用技術(shù)) |
處理 | 阻塞IO(多線程) | 非阻塞IO(反應(yīng)堆Reactor) |
觸發(fā) | 無 | 選擇器(輪詢機制) |
-
3.2盲厌、對比之面向流與面向緩沖區(qū)
Java NIO 和 BIO 之間第一個最大的區(qū)別是署照,BIO 是面向流
的,NIO 是面向緩沖區(qū)
的吗浩。
Java BIO 面向流意味著每次從流中讀一個或多個字節(jié)藤树,直至讀取所有字節(jié),它們沒有被緩存在任何地方拓萌。此外岁钓,它不能前后移動流中的數(shù)據(jù)。 如果需要前后移動從流中讀取的數(shù)據(jù)微王,需要先將它緩存到一個緩沖區(qū)屡限。
Java NIO 面向緩沖區(qū)導(dǎo)向方法略有不同。數(shù)據(jù)讀取到一個它稍后處理的緩沖區(qū)炕倘,需要時可在緩沖區(qū)中前后移動钧大。這就增加了處理過程中的靈活性。
-
3.3罩旋、對比之阻塞與非阻塞
Java BIO 的各種流是阻塞的啊央。這意味著,當(dāng)一個線程調(diào)用 read() 或 write()時涨醋,該線程被阻塞瓜饥,直到有一些數(shù)據(jù)被讀取,或數(shù)據(jù)完全寫入浴骂。該線程在此期間不能再干任何事情了乓土。
Java NIO 的非阻塞模式,使一個線程【boss線程】從某通道發(fā)送請求讀取數(shù)據(jù),但是它僅能得到目前可用的數(shù)據(jù)趣苏,如果目前沒有數(shù)據(jù)可用時狡相,就什么都不會獲取,而不是保持線程阻塞食磕, 所以直至數(shù)據(jù)變的可以讀取之前尽棕,該線程可以繼續(xù)做其他的事情。 非阻塞寫也是如此彬伦。一個線程請求寫入一些數(shù)據(jù)到某通道萄金,但不需要等待它完全寫入,這個線程同時可以去做別的事情媚朦。 線程通常將非阻塞 IO 的空閑時間用于在其它通道上執(zhí)行 IO 操作,所以一個單獨的線程現(xiàn)【boss線程】在可以管理多個輸入和輸出通道(channel)日戈。
-
3.4询张、selector選擇器問世
Java NIO 的選擇器(Selector)允許一個單獨的線程來監(jiān)視多個輸入通道,你可以注冊多個通道使用一個選擇器浙炼,然后使用一個單獨的線程來選擇通道:這些通道里已經(jīng)有可以處理的輸入份氧,或者選擇已準(zhǔn)備寫入的通道。這種選擇機制弯屈, 使得一個單獨的線程很容易來管理多個通道蜗帜。
-
3.5、NIO 和 BIO 讀取磁盤數(shù)據(jù)的對比
-
3.5.1资厉、java BIO模式讀取磁盤數(shù)據(jù):
-
/**
* @description: java 阻塞IO從磁盤讀取txt文件
**/
public class ReadTxtDemo {
private static String fileName="/xxxx/io/bio/txt/source.txt";
public static void main(String[] args) throws IOException {
readTxtFile(fileName);
}
private static void readTxtFile(String fileName) throws IOException {
FileInputStream input = new FileInputStream(fileName);
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
while (true) {
String str = reader.readLine();
if(str!=null)
System.out.println(str);
else
break;
}
reader.close();
input.close();
}
}
控制臺輸出:
name:biudefu
age:18
email:biudefu@qq.com
phone:18666666666
Process finished with exit code 0
-
3.5.2厅缺、java NIO模式讀取磁盤數(shù)據(jù):
/**
* @description: java 非阻塞IO,nio方式宴偿,讀取磁盤文件
**/
public class NioReadTxtDemo {
private static String fileName="/xxxx/txt/source.txt";
public static void main(String[] args) throws IOException {
readTxtFile(fileName);
}
private static void readTxtFile(String fileName) throws IOException {
FileInputStream f1 = new FileInputStream(fileName);
FileChannel channel = f1.getChannel();
ByteBuffer b1 = ByteBuffer.allocate(8);//初始化緩沖區(qū)大小
int length ;
while ((length = channel.read(b1)) != -1) {
b1.clear();
byte[] bytes = b1.array();
System.out.write(bytes, 0, length);
}
channel.close();
}
}
控制臺輸出:
name:biudefu
age:18
email:biudefu@qq.com
phone:18666666666
Process finished with exit code 0
-
3.6湘捎、BIO、NIO窄刘、AIO應(yīng)用場景
屬性 | 同步阻塞IO | 偽異步IO | 非阻塞IO(NIO) | 異步IO(AIO) |
---|---|---|---|---|
阻塞類型 | 阻塞 | 阻塞 | 非阻塞 | 非阻塞 |
同步類型 | 同步 | 同步 | 同步(多路復(fù)用) | 異步 |
API使用難度 | 簡單 | 簡單 | 復(fù)雜 | 一般 |
調(diào)試難度 | 簡單 | 簡單 | 復(fù)雜 | 復(fù)雜 |
可靠性 | 非常差 | 差 | 高 | 高 |
吞吐量 | 低 | 中 | 高 | 高 |
4窥妇、Unix網(wǎng)絡(luò)編程5種I/O模型 !C浼;铘妗!翻伺!圖有問題需要修改2男埂!6至搿A嘲!未妹!
-
4.1簿废、阻塞I/O(準(zhǔn)備數(shù)據(jù)+復(fù)制數(shù)據(jù)均是阻塞)(
同步阻塞IO
)
-
4.2空入、非阻塞I/O(準(zhǔn)備數(shù)據(jù)非阻塞,復(fù)制數(shù)據(jù)阻塞)(
同步非阻塞IO
)
-
4.3族檬、多路復(fù)用I/O(準(zhǔn)備數(shù)據(jù)+復(fù)制數(shù)據(jù)均是阻塞)(
同步非阻塞IO
)
-
4.4歪赢、信號驅(qū)動I/O(準(zhǔn)備數(shù)據(jù)非阻塞,復(fù)制數(shù)據(jù)阻塞)(
異步非阻塞IO
)
-
4.5单料、異步I/O(準(zhǔn)備數(shù)據(jù)+復(fù)制數(shù)據(jù)均是非阻塞)(
異步非阻塞IO
)
5埋凯、面試常見問題
-
5.1、流按照傳輸?shù)姆较蛟趺捶诸悾?/h6>
相對于內(nèi)存
來說扫尖,流按照傳輸方向白对,可以分為輸入流InputStream、輸出流OutputStream换怖。
-
5.2甩恼、流按照傳輸?shù)膯挝辉趺捶诸悾糠殖赡膬煞N流,并且他們的父類叫什么沉颂?說一下常用的IO流条摸?
流按照傳輸單位分為 字節(jié)流 和 字符流
字節(jié)流的抽象基類(父類)是:java.io.InputStream、java.io.OutputStream
字符流的抽象基類(父類)是:java.io.Reader 铸屉、java.io.Writer
-
5.3钉蒲、流按實現(xiàn)功能怎么分?
按照功能分為:節(jié)點流 OutputStream彻坛、處理流 OutputStreamWriter
節(jié)點流 :直接與數(shù)據(jù)源(文件等)相連顷啼,用于輸入或輸出。
處理流:在節(jié)點流的基礎(chǔ)上對之進行加工昌屉,進行一些功能的擴展线梗。
處理流的構(gòu)造器必須要 傳入節(jié)點流的子類。
-
5.4怠益、FileInputStream和FileOutputStream 與 BufferedInputStream 和 BufferedOutputStream區(qū)別仪搔?
這是在拷貝文件操作的時候,經(jīng)常用到的兩個類蜻牢。在處理小文件的時候烤咧,F(xiàn)ileInputStream和FileOutputStream性能表現(xiàn)還不錯,在大文件的時候抢呆,最好使用BufferedInputStream(或BufferedReader)和BufferedOutputStream(或BufferedWriter)煮嫌。
-
5.5、flush() 方法的作用抱虐?
flush()方法可以強迫輸出流(或緩沖的流)發(fā)送數(shù)據(jù)昌阿,即使此時緩沖區(qū)還沒有填滿,以此來打破這種死鎖的狀態(tài)。
-
5.6懦冰、什么是同步阻塞IO灶轰,什么是同步非阻塞IO,什么是異步阻塞IO刷钢?什么是異步非阻塞IO笋颤?
- 同步阻塞IO:丟衣服->站在洗衣機前面,直到洗衣機洗完->再去晾衣服内地。
- 同步非阻塞IO:丟衣服->去做其他事情伴澄,定時去看衣服是否洗完->洗完后自己去晾衣服。
- 異步阻塞IO:丟衣服-> 站在洗衣機前面阱缓,直到洗衣機洗完非凌,洗衣機會發(fā)出聲響
通知你
->再去晾衣服。 - 異步非阻塞IO:丟衣服-> 去做其他事情荆针,衣服洗好會自動晾好敞嗡,并且發(fā)出聲音
通知你
晾好了。
tips:同步&異步是指洗衣機會不會通知你祭犯。阻塞&非阻塞是指在洗衣服期間你還可不可以干別的?
-
5.6滚停、IO模型有幾種沃粗?分別是什么?
- 阻塞 IO键畴、非阻塞 IO最盅、多路復(fù)用 IO、信號驅(qū)動 IO起惕、異步 IO涡贱,其中前三種是同步,且內(nèi)核數(shù)據(jù) copy 到用戶空間時是阻塞的惹想。
- 如上圖IO五種模式问词。
-
5.7、五種IO模型在java中是如何支持的嘀粱?
- 同步阻塞IO:BIO中 當(dāng)沒有請求 or 沒有響應(yīng)(socket.accept()激挪、socket.read()、socket.write()方法)函數(shù)無法進行有效的中斷锋叨。
- 同步非阻塞IO(多路復(fù)用IO):NIO中 java.nio.channels.ServerSocketChannel 中的accept()等讀寫函數(shù)可以立刻返回垄分。
- 異步非阻塞IO:AIO中的java.nio.channels.AsynchronousServerSocketChannel 中的accept()方法。