透徹理解JavaIO

記-更加深刻理解Java IO

Java IO讀寫原理

  • 在Java層面的應用開發離不開輸入流 Input 和 輸出流 Output 的處理,簡稱爲IO讀寫
  • 用戶程序在進行IO讀寫操作的時候,離不開 read&write 的調用
  • 需要注意的是IO讀寫並不是物理設備和內存之間的相互讀寫
  • 以read系統爲代表的輸入流,是把數據從內核緩衝區複製到進程緩衝區
  • 以write系統爲代表的輸出流,是把數據從進程緩衝區複製到內核緩衝區
  • 內核緩衝區和磁盤之間的數據讀寫交換,由操作系統內核完成

Q:什麼是內核緩衝區?

  • 操作系統的內核擁有對應的內核緩衝區

Q:什麼是進程緩衝區?

  • 每一個進程擁有進程緩衝區

Q:緩衝區存在的目的?

  • 減少頻繁的系統IO調用,提高性能

java IO讀寫流程

  • 我們通常會使用到這樣的代碼
//  client
OutputStream os = socket.getOutputStream();
os.write("xxx");
//  server
InputStream is = socket.getInputStream();
is.read();
  • client發起一次請求,os.write輸出流,把數據從進程緩衝區複製到內核緩衝區
  • server接收請求,is.read把數據從內核緩衝區複製到進程緩衝區

關於同步和異步

  • 同步(Synchronization)異步(Synchronization)
  • 同步和異步是基於應用程序和操作系統處理IO所採用的方式
  • 同步:一旦開始一個“過程”,調用者必須等到“過程”結束返回結果,才能繼續後續的行爲
  • 異步:調用者會立即收到反饋,調用者可以進行後續操作而不會受到影響
  • 同步IO :用戶空間線程主動發起IO請求,內核空間被動接受
  • 異步IO :內核kernel是主動發起IO請求的一方,用戶線程是被動接受方

阻塞和非阻塞

  • 阻塞(Block)非阻塞(Non-Block)
  • 阻塞和非阻塞是進程在訪問數據的時候,數據是否處理就緒的一種處理方式
  • 阻塞:需要等待數據處理完畢,才能進行後續操作
  • 非阻塞:無論數據是否準備好,立即返回一個結果
  • 阻塞IO : 用戶空間需要等待內核IO操作徹底完成。直到其返回一個結果。
  • 非阻塞IO :內核IO操作無論是否完成,會立即反饋給用戶一個狀態值,用戶空間無需等待

IO模型

  • 通過對同步、異步、阻塞和非阻塞有了一個初步的認識過後
  • 方便我們更加透徹理解IO模型

BIO 即 同步阻塞IO (Block IO)

  • 在Linux系統的Java進程中,默認所有的socket都是 blocking IO 即 阻塞IO
  • 應用程序從發起IO調用開始直到系統返回,這段時間是阻塞的。返回成功後,應用程序纔會去處理後續邏輯

在這裏插入圖片描述

僞異步IO

  • 通過設置socket實現non-blocking
  • NIO模型中,應用程序開始調用,有以下兩種情況
    • 在內核緩衝區沒有數據的情況下,系統調用會立即返回一個調用失敗的信息
    • 在內核緩衝區有數據的情況下,是阻塞的,直到IO操作完成,返回成功結果
  • 由於存在阻塞的情況,所以又稱爲僞異步IO

NIO—非阻塞IO

  • 瞭解NIO之前需要明白:什麼是多路複用
  • 多路複用模型
    • 一個進程可以監視多個狀態(FD),一旦某個狀態就緒,內核發出反饋完成後續操作
  • 典型的IO多路複用模型有 Java Selector、epoll
  • 基本原理
    • 非阻塞IO的實現基於select/epoll系統的調用,單個線程輪詢所負責的socket連接
    • 當有socket連接的數據到達時,就返回這些都進行讀寫的連接

AIO (Asynchronous IO)

  • 異步AIO,把IO讀寫操作完全交給操作系統
  • 基本流程
    • 用戶線程通過系統調用,告知kernel內核啓動某個IO操作,用戶線程返回。
    • kernel內核在整個IO操作(包括數據準備,數據複製)完成後,通知用戶,用戶執行後續操作
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章