• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • 網絡編程-BIO、NIO、AIO的原理與對比

    標簽: java  多線程  socket  nio

    什么是同步異步

    同步和異步是針對應用程序和內核交互而言的。同步指的是用戶進程觸發IO操作并等待或者輪詢查看IO操作是否就緒。而異步就是指用戶進程觸發IO操作后便開始干自己的事情,當IO操作完成后,用戶會得到IO完成的通知。

    舉個栗子:

    同步:自己去銀行取錢。去了銀行申請業務,等待叫號,處理完回家

    異步:委托他人代為操作,自己可以干別的,等他人取完錢交給自己。

    OS操作系統底層支持異步IO操作。


    什么是阻塞和非阻塞

    阻塞和非阻塞是針對遠程訪問數據的時候,根據IO操作的就緒狀態采取的不同的方式。說白了就是一種讀取或者寫入操作函數實現方式。

    阻塞方式下讀取或者寫入,行數將一直等待,而非阻塞方式下,讀取或者寫入函數會立刻返回一個狀態值

    舉個栗子:

    阻塞:ATM排隊取款,你只能等待(使用阻塞IO時,Java會一直阻塞到讀寫完成才退出這個函數)

    非阻塞:柜臺取款,取號,然后坐在等待區椅子上,等待廣播叫號通知你辦理,沒叫到你你就不能去。但是這個期間你可以不斷地詢問大堂經理排到你了沒有。大堂經理會告訴你一個結果(使用非阻塞IO時,如果不能讀寫,Java調用會立刻返回。當IO事件分發器通知可以讀寫時,再繼續進行讀寫,不斷循環直到結束)

    通過例子可以看出,你去取錢,自己去和不是自己去,跟去了使用ATM還是柜臺辦理,是沒有任何關系的。也就是說阻塞非阻塞和同步異步并沒有直接的關系。同步異步是使用多線程完成的,而阻塞非阻塞是這個線程需不需要等待前面的事務完成


    BIO

    同步阻塞編程方式。

    就相當于你去銀行辦理業務,而且你使用了ATM取款機(只能自己處理事件,若服務端繁忙就會阻塞,等待服務端響應)

    BIO編程方式通常是jdk1.4版本之前使用的編程方式。編程實現過程:首先在服務端啟動一個ServerSocket來監聽網絡請求,客戶端啟動Socket發起網絡請求,默認情況下ServerSocket會建立一個線程來處理此請求,如果服務端沒有線程可用,客戶端則會阻塞等待或遭到拒絕

    大致結構如下:

    在這里插入圖片描述

    服務端線程與客戶端一一對應,處理客戶端請求

    可以通過線程池來優化BIO,避免高并發情況下服務端線程過多

    客戶端與服務端線程之間建立的鏈接屬于長連接。長連接的特點就是數據可以多次往返。(HTTP協議通常是短連接,一個請求一個應答就會結束)

    同步并阻塞: 服務器實現模式為:一個client鏈接一個server線程。即客戶端有鏈接請求時服務器端就需要啟動一個線程進行處理,如果這個鏈接什么事情也沒干,就會造成不必要的線程開銷。這一點可以通過線程池優化。

    BIO適用于 鏈接數目比較小且固定的架構,這種方式對服務器資源要求比較高,并發局限于應用中,JDK1.4前這是唯一的選擇。但是程序直觀簡單容易理解。

    使用線程池改善后的模型圖如下:

    在這里插入圖片描述


    NIO

    同步非阻塞的編程方式。

    就比如說,你去銀行取錢,你選擇叫號(同步非阻塞),你在叫號機上選擇買燒餅,但是叫號機并沒有這個選項,你就沒法叫到號,也就沒有柜臺處理你買燒餅的業務(得不到服務器線程)。

    NIO本身是基于事件驅動思想來完成的,其主要想解決的是BIO的大并發問題。NIO基于Reactor,當Socket有流可讀或可寫入socket時,操作系統會相應的通知應用程序進行處理,應用程序再將流讀取到緩沖區或寫入操作系統。也就是說,這個時候,不是說有一個鏈接就會有一個線程來處理,而是有效的請求,才會有線程處理。當一個鏈接沒有數據時,是沒有線程來處理的。

    NIO的最重要的地方是當一個鏈接創建后,不需要對應一個線程,這個鏈接會被注冊到多路復用器上面,當這個線程中的多路復用器進行輪詢的時候,發現連接上有請求,才開啟一個線程處理請求。這個時候就進入了一個請求一個線程的模式。

    在NIO中,當一個請求被線程處理時,可能會等待其他的資源比如數據庫的資源,其實在等待數據庫資源時這個線程就以及阻塞了。并發量很大的情況下還是可能會有BIO的問題,只不過這種情況就不說client鏈接中沒有請求了,而且請求沒法被及時的回應。
    NIO模型如下

    在這里插入圖片描述

    同步非阻塞: 實現模式為一個IO請求一個線程,客戶端發送的所有鏈接都會被注冊到多路復用器上,多路復用器輪詢檢查鏈接是否有I/O操作,有IO請求時才會啟動一個線程進行處理。

    NIO模式適用于 連接數目多,且鏈接操作比較輕的架構,比如聊天服務器。并發局限于應用中,編程復雜,JDK1.4開始支持

    AIO

    異步非阻塞編程方式

    在JDK1.7引入相關概念

    與NIO不同,當進行讀寫操作時,只需調用API的read和write方法即可。這兩種方法均為異步操作。對于讀操作而言,當有流可以進行讀取時,操作系統會將可讀的流傳入Read方法的緩沖區,并通知應用程序;對于寫操作而言,當操作系統將write方法傳遞的流寫入完畢時,操作系統主動通知應用程序。也就是說read和write方法都是異步的,完成后會主動調用回調函數。在JDK1.7中,這個部分的內容被稱作NIO.2。主要在Java.nio.channels包下增加了四個異步通道:

       AsynchronousSocketChannel
    
       AsynchronousServerSocketChannel
    
       AsynchronousFileChannel
    
       AsynchronousDatagramChannel
    

    異步非阻塞: 服務器實現模式為一個有效請求一個線程,客戶端的IO都是由OS操作系統完成的,再通知服務器取啟動線程進行處理。

    AIO方式適用于鏈接數目較多且操作較重的架構,比如QQ空間相冊的那種感覺的,充分調用OS參與并發操作,編程復雜,從JDK1.7開始支持

    參考視頻鏈接
    https://www.bilibili.com/video/BV1mE411d7nb?p=1
    眾所周知,B站是用來學習的在這里插入圖片描述

    版權聲明:本文為jsx____原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/jsx____/article/details/108477675

    智能推薦

    BIO、NIO、AIO原理及總結

    同步阻塞IO(BIO) 原理 同步并阻塞,服務器實現模式為一個連接一個線程,即客戶端有連接請求時服務器端就需要啟動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷。 上面這個代碼很簡單,轉換成圖型說明就是web瀏覽器發一個請求過來,web服務器就要new 一個線程來處理這個請求,這是傳統的請求處理模型。 這也就引來一個很大的問題,當請求越多,服務器端的啟用線程也要越多,我們都知道l...

    Java 網絡IO(BIO,NIO,AIO)

    Java 網絡IO(BIO,NIO,AIO) 1.BIO BIO 全稱Block-IO 是一種同步阻塞的通信模式。我們常說的Stock IO 一般指的是BIO。是一個比較傳統的通信方式,模式簡單,使用方便。但并發處理能力低,通信耗時,依賴網速。 BIO 設計原理: 服務器通過一個Acceptor線程負責監聽客戶端請求和為每個客戶端創建一個新的線程進行鏈路處理。典型的一請求一應答模式。若客戶端數量增...

    Java網絡BIO、NIO、AIO相關

    原文 目錄: BIO (Blocking I/O) NIO (New I/O) AIO (Asynchronous I/O) BIO,NIO,AIO 總結 Java 中的 BIO、NIO和 AIO 理解為是 Java 語言對操作系統的各種 IO 模型的封裝。程序員在使用這些 API 的時候,不需要關心操作系統層面的知識,也不需要根據不同操作系統編寫不同的代碼。只需要使用Java的API就可以了。 ...

    一文搞定網絡編程中的BIO、NIO和AIO(從理論到代碼演示)

    在學習網絡編程時,容易混淆NIO、BIO、AIO這幾個概念,同時對于阻塞和非阻塞、同步和異步的理解也較為晦澀,本文將從最基礎的內核態/用戶態進行介紹,逐步講解在Java的IO編程中幾種不同IO操作方式及其具體實現。 BIO\NIO\AIO解析 1. Linux網絡IO模型介紹 1.1 基本概念 1.1.1 內核空間和用戶空間 1.1.2 內核態和用戶態 1.1.3 如何從用戶空間到內核空間 1.2...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    猜你喜歡

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    Linux C系統編程-線程互斥鎖(四)

    互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...

    精品国产乱码久久久久久蜜桃不卡