Netty-基礎篇(1)-網(wǎng)絡IO,同步IO&異步IO,阻塞IO&非阻塞IO,BIO&NIO&AIO

高達00-人物

目錄:

  • 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 類比貨車拉貨
  • 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應用場景
  • 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ū)別:

阻塞和非阻塞是服務端進程(線程)在訪問數(shù)據(jù)的時候,數(shù)據(jù)是否準備就緒的一種處理方式:

  • 阻塞(Block):需要等待緩沖區(qū)中的數(shù)據(jù)準備好過后才處理其他的事情,否則一直等待在那里。
    • eg:SeverSocket 中的accept() 。
  • 非阻塞(Non-Block):進程訪問數(shù)據(jù)緩沖區(qū)的時候,如果數(shù)據(jù)沒有準備好則直接返回,不會等待。如果數(shù)據(jù)已經(jīng)準備好,也直接返回。
    • nio 中的Selector 。
1.2、阻塞IO(Block IO)與非阻塞IO(Non-Block IO) 圖解:
阻塞IO

非阻塞IO

2、同步IO (Syn IO)與異步IO (Asyn IO)

2.1、同步IO(Syn IO)和異步IO(Asyn IO)的對比:

同步和異步都是基于服務端處理請求采用的方式:

  • eg:
    • 同步(Synchronization):client發(fā)出請求到服務端,無論服務端是否阻塞以及其他情況,只要服務端同步返回結(jié)果,就認定是同步。
    • 異步(Asynchronous):client發(fā)出請求到服務端,同步返回值中沒有結(jié)果,Client只需要等待通知,收到通知后才能拉取結(jié)果,就是異步。
2.2、同步IO和異步IO還是比較抽象的,繼續(xù)類比:
  • 同步IO,可以類比客戶端與服務端通信方式采用RPC方式,同步給返回結(jié)果。
  • 異步IO,可以類比客戶端與服務端通信方式采用MQ+RPC方式,異步給客戶端一個通知,Client端再通過RPC同步返回結(jié)果。
2.3、同步IO和異步IO 類比生活中貨車拉貨:
同步IO

異步IO

3、BIO、NIO、AIO

3.1、Java BIO(Block IO)和 NIO(Non-Block IO)之間的主要差別異:
IO模型 BIO NIO
通信 面向流 面向緩沖區(qū)(多路復用技術(shù))
處理 阻塞IO(多線程) 非阻塞IO(反應堆Reactor)
觸發(fā) 選擇器(輪詢機制)
  • 3.2、對比之面向流與面向緩沖區(qū)

Java NIO 和 BIO 之間第一個最大的區(qū)別是,BIO 是面向的,NIO 是面向緩沖區(qū)的。
Java BIO 面向流意味著每次從流中讀一個或多個字節(jié),直至讀取所有字節(jié),它們沒有被緩存在任何地方。此外,它不能前后移動流中的數(shù)據(jù)。 如果需要前后移動從流中讀取的數(shù)據(jù),需要先將它緩存到一個緩沖區(qū)。
Java NIO 面向緩沖區(qū)導向方法略有不同。數(shù)據(jù)讀取到一個它稍后處理的緩沖區(qū),需要時可在緩沖區(qū)中前后移動。這就增加了處理過程中的靈活性。

  • 3.3、對比之阻塞與非阻塞

Java BIO 的各種流是阻塞的。這意味著,當一個線程調(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)有可以處理的輸入,或者選擇已準備寫入的通道。這種選擇機制, 使得一個單獨的線程很容易來管理多個通道。

  • 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
BIO面向的是流
  • 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
NIO面向的是緩沖區(qū)
  • 3.6、BIO、NIO、AIO應用場景
屬性 同步阻塞IO 偽異步IO 非阻塞IO(NIO) 異步IO(AIO)
阻塞類型 阻塞 阻塞 非阻塞 非阻塞
同步類型 同步 同步 同步(多路復用) 異步
API使用難度 簡單 簡單 復雜 一般
調(diào)試難度 簡單 簡單 復雜 復雜
可靠性 非常差
吞吐量

4、Unix網(wǎng)絡編程5種I/O模型 !!!!!圖有問題需要修改!!!!!!

  • 4.1、阻塞I/O(準備數(shù)據(jù)+復制數(shù)據(jù)均是阻塞)(同步阻塞IO
阻塞IO
  • 4.2、非阻塞I/O(準備數(shù)據(jù)非阻塞,復制數(shù)據(jù)阻塞)(同步非阻塞IO
非阻塞IO
  • 4.3、多路復用I/O(準備數(shù)據(jù)+復制數(shù)據(jù)均是阻塞)(同步非阻塞IO
多路復用IO
  • 4.4、信號驅(qū)動I/O(準備數(shù)據(jù)非阻塞,復制數(shù)據(jù)阻塞)(異步非阻塞IO
信號驅(qū)動IO
  • 4.5、異步I/O(準備數(shù)據(jù)+復制數(shù)據(jù)均是非阻塞)(異步非阻塞IO
異步IO

5、面試常見問題

  • 5.1、流按照傳輸?shù)姆较蛟趺捶诸悾?/h6>

相對于內(nèi)存來說,流按照傳輸方向,可以分為輸入流InputStream、輸出流OutputStream

  • 5.2、流按照傳輸?shù)膯挝辉趺捶诸悾糠殖赡膬煞N流,并且他們的父類叫什么?說一下常用的IO流?

流按照傳輸單位分為 字節(jié)流字符流
字節(jié)流的抽象基類(父類)是:java.io.InputStreamjava.io.OutputStream
字符流的抽象基類(父類)是:java.io.Readerjava.io.Writer

  • 5.3、流按實現(xiàn)功能怎么分?

按照功能分為:節(jié)點流 OutputStream、處理流 OutputStreamWriter
節(jié)點流 :直接與數(shù)據(jù)源(文件等)相連,用于輸入或輸出。
處理流:在節(jié)點流的基礎上對之進行加工,進行一些功能的擴展。
處理流的構(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、多路復用 IO、信號驅(qū)動 IO、異步 IO,其中前三種是同步,且內(nèi)核數(shù)據(jù) copy 到用戶空間時是阻塞的。
    • 如上圖IO五種模式。
  • 5.7、五種IO模型在java中是如何支持的?
    • 同步阻塞IO:BIO中 當沒有請求 or 沒有響應(socket.accept()、socket.read()、socket.write()方法)函數(shù)無法進行有效的中斷。
    • 同步非阻塞IO(多路復用IO):NIO中 java.nio.channels.ServerSocketChannel 中的accept()等讀寫函數(shù)可以立刻返回。
    • 異步非阻塞IO:AIO中的java.nio.channels.AsynchronousServerSocketChannel 中的accept()方法。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。