日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

也谈BIO | NIO | AIO (Java版--转)

發布時間:2025/4/5 java 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 也谈BIO | NIO | AIO (Java版--转) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://my.oschina.net/bluesky0leon/blog/132361

關于BIO | NIO | AIO的討論一直存在,有時候也很容易讓人混淆,就我的理解,給出一個解釋:

BIO | NIO | AIO,本身的描述都是在Java語言的基礎上的。而描述IO,我們需要從兩個層面:

  • 編程語言
  • 實現原理
  • 底層基礎
  • 從編程語言層面

    BIO | NIO | AIO 以Java的角度,理解,linux c里也有AIO的概念(庫),這些概念不知道什么原因被炒火起來,這里只從Java角度入手。

    • BIO,同步阻塞式IO,簡單理解:一個連接一個線程
    • NIO,同步非阻塞IO,簡單理解:一個請求一個線程
    • AIO,異步非阻塞IO,簡單理解:一個有效請求一個線程

    BIO

    在JDK1.4之前,用Java編寫網絡請求,都是建立一個ServerSocket,然后,客戶端建立Socket時就會詢問是否有線程可以處理,如果沒有,要么等待,要么被拒絕。即:一個連接,要求Server對應一個處理線程。

    NIO

    在Java里的由來,在JDK1.4及以后版本中提供了一套API來專門操作非阻塞I/O,我們可以在java.nio包及其子包中找到相關的類和接口。由于這套API是JDK新提供的I/O API,因此,也叫New I/O,這就是包名nio的由來。這套API由三個主要的部分組成:緩沖區(Buffers)、通道(Channels)和非阻塞I/O的核心類組成。在理解NIO的時候,需要區分,說的是New I/O還是非阻塞IO,New I/O是Java的包,NIO是非阻塞IO概念。這里講的是后面一種。

    NIO本身是基于事件驅動思想來完成的,其主要想解決的是BIO的大并發問題: 在使用同步I/O的網絡應用中,如果要同時處理多個客戶端請求,或是在客戶端要同時和多個服務器進行通訊,就必須使用多線程來處理。也就是說,將每一個客戶端請求分配給一個線程來單獨處理。這樣做雖然可以達到我們的要求,但同時又會帶來另外一個問題。由于每創建一個線程,就要為這個線程分配一定的內存空間(也叫工作存儲器),而且操作系統本身也對線程的總數有一定的限制。如果客戶端的請求過多,服務端程序可能會因為不堪重負而拒絕客戶端的請求,甚至服務器可能會因此而癱瘓。

    NIO基于Reactor,當socket有流可讀或可寫入socket時,操作系統會相應的通知引用程序進行處理,應用再將流讀取到緩沖區或寫入操作系統。?
    也就是說,這個時候,已經不是一個連接就要對應一個處理線程了,而是有效的請求,對應一個線程,當連接沒有數據時,是沒有工作線程來處理的。

    AIO

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

    • AsynchronousSocketChannel
    • AsynchronousServerSocketChannel
    • AsynchronousFileChannel
    • AsynchronousDatagramChannel

    其中的read/write方法,會返回一個帶回調函數的對象,當執行完讀取/寫入操作后,直接調用回調函數。

    實現原理

    說道實現原理,還要從操作系統的IO模型上了解

    按照《Unix網絡編程》的劃分,IO模型可以分為:阻塞IO、非阻塞IO、IO復用、信號驅動IO和異步IO,按照POSIX標準來劃分只分為兩類:同步IO和異步IO。如何區分呢?首先一個IO操作其實分成了兩個步驟:發起IO請求和實際的IO操作,同步IO和異步IO的區別就在于第二個步驟是否阻塞,如果實際的IO讀寫阻塞請求進程,那么就是同步IO,因此阻塞IO、非阻塞IO、IO復用、信號驅動IO都是同步IO,如果不阻塞,而是操作系統幫你做完IO操作再將結果返回給你,那么就是異步IO。阻塞IO和非阻塞IO的區別在于第一步,發起IO請求是否會被阻塞,如果阻塞直到完成那么就是傳統的阻塞IO,如果不阻塞,那么就是非阻塞IO。

    收到操作系統的IO模型,又不得不提select/poll/epoll/iocp,關于這四個的理解,不多做解釋,自己還沒理解到位。

    可以理解的說明是:在Linux 2.6以后,java NIO的實現,是通過epoll來實現的,這點可以通過jdk的源代碼發現。而AIO,在windows上是通過IOCP實現的,在linux上還是通過epoll來實現的。

    這里強調一點:AIO,這是I/O處理模式,而epoll等都是實現AIO的一種編程模型;換句話說,AIO是一種接口標準,各家操作系統可以實現也可以不實現。在不同操作系統上在高并發情況下最好都采用操作系統推薦的方式。Linux上還沒有真正實現網絡方式的AIO。

    底層基礎

    說到底層,要說Linux系統編程,這里自己也不熟悉,有待后來人補充了。?
    只籠統的說一個:AIO實現

    在windows上,AIO的實現是通過IOCP來完成的,看JDK的源代碼,可以發現

    WindowsAsynchronousSocketChannelImpl

    看實現接口:

    implements Iocp.OverlappedChannel

    再看實現方法:里面的read0/write0方法是native方法,調用的jvm底層實現,虛擬機技術不熟悉,不獻丑了。

    在linux上,AIO的實現是通過epoll來完成的,看JDK源碼,可以發現,實現源碼是:

    UnixAsynchronousSocketChannelImpl

    看實現接口:

    implements Port.PollableChannel

    這是與windows最大的區別,poll的實現,在linux2.6后,默認使用epoll。

    這樣就可以理解了。

    寫在最后:Java開發為基礎的,對于操作系統底層的認知是沒有C語言為基礎的大牛好的,語言決定了思維方式,古人誠不欺我

    最后,幾篇解釋的不錯的文章:

    BIO NIO AIO

    NIO.2 入門,第 1 部分: 異步通道 API

    使用異步 I/O 大大提高應用程序的性能

    轉載于:https://www.cnblogs.com/davidwang456/p/3521343.html

    總結

    以上是生活随笔為你收集整理的也谈BIO | NIO | AIO (Java版--转)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。