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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java中的io复用_从 Java 中的零拷贝到五种IO模型

發(fā)布時(shí)間:2025/3/12 java 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java中的io复用_从 Java 中的零拷贝到五种IO模型 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在之前的文章中,我們聊過了 Java 中的零拷貝,零拷貝就是指數(shù)據(jù)不會(huì)在內(nèi)核空間和用戶空間之間相互拷貝。這樣就減少了內(nèi)核態(tài)與用戶態(tài)的切換,自然就很高效。

拷貝文件只是 IO 操作中一個(gè)特殊的情況,大多數(shù)的 IO 操作還是需要將數(shù)據(jù)從內(nèi)核空間移到用戶空間,這往往是一個(gè)比較耗時(shí)的操作。

IO 操作不僅僅指對(duì)文件的讀寫,網(wǎng)絡(luò)的通信同樣也是 IO 操作。

如今很多系統(tǒng)的瓶頸就在于 IO 上,比如經(jīng)典的 C10K,C10M 問題本質(zhì)上就是在解決 IO 問題。

這篇文章將介紹經(jīng)典的 IO 模型的實(shí)現(xiàn)原理,以及說明 Java IO 與這幾種 IO 模型的關(guān)系。

💡本文討論的環(huán)境為 Linux

IO 操作是怎么實(shí)現(xiàn)的

IO 操作是一個(gè)很復(fù)雜的過程,遠(yuǎn)遠(yuǎn)不止調(diào)用一個(gè)函數(shù)那么簡單,因?yàn)槊恳淮蔚?IO 操作都會(huì)涉及到操作系統(tǒng)的內(nèi)核空間和用戶空間的轉(zhuǎn)換,真正執(zhí)行的 IO 操作實(shí)際上是在操作系統(tǒng)的內(nèi)核空間進(jìn)行。

這是一個(gè)很耗資源的操作。計(jì)算機(jī)中內(nèi)存和 CPU 都是非常稀有的資源,應(yīng)該盡可能提高這些資源的使用效率。

IO 操作經(jīng)常需要與磁盤就行交互,所以IO 操作相比于 CPU 的速度要慢好幾個(gè)數(shù)量級(jí)。利用這兩者之間的速度差異,就可以實(shí)現(xiàn)不同種類的 IO 方式,也就是俗稱的 IO 模型。

當(dāng)然,這些 IO 操作的都在操作系統(tǒng)層面上實(shí)現(xiàn)好了,編程語言可以利用這些能力去實(shí)現(xiàn) IO 相關(guān)的 API。

五種 IO 模型

在 操作系統(tǒng)中,IO 模型有如下五種:

在上文已經(jīng)說到,其實(shí) IO 操作就是將數(shù)據(jù)在用戶空間與內(nèi)核空間進(jìn)行相互轉(zhuǎn)換,這個(gè)過程是通過系統(tǒng)調(diào)用來完成的。 IO 技術(shù)的發(fā)展目標(biāo)就是如何使用盡可能少的資源來完成數(shù)據(jù)的傳輸,這里資源主要就是指 CPU 資源。

無論是文件 IO,還是網(wǎng)絡(luò) IO,最后都可以統(tǒng)一為用戶空間和內(nèi)核空間數(shù)據(jù)的交換。

BIO

BIO 是最經(jīng)典的一種 IO 方式,也是最簡單粗暴的方式,在發(fā)起 IO 操作之后,當(dāng)前調(diào)用線程就會(huì)處在阻塞狀態(tài),直到數(shù)據(jù)傳輸完成。

NIO

NIO 是在 BIO 基礎(chǔ)之上的一個(gè)改進(jìn),NIO 在數(shù)據(jù)還未準(zhǔn)備好的情況下,不會(huì)阻塞進(jìn)程,而是通過輪詢的方式,不斷的去查詢數(shù)據(jù)時(shí)候準(zhǔn)備好,當(dāng)數(shù)據(jù)可以被讀取時(shí),當(dāng)前線程就會(huì)處在阻塞狀態(tài),直到數(shù)據(jù)讀取完成。

所以 NIO 中的非阻塞指的是在等待數(shù)據(jù)的階段,實(shí)際進(jìn)行數(shù)據(jù)傳輸時(shí),還是阻塞的,這點(diǎn)需要注意。

IO 多路復(fù)用

IO 多路復(fù)用是對(duì) NIO 的一個(gè)改進(jìn),在 NIO 中,需要不斷輪詢查看數(shù)據(jù)是否準(zhǔn)備好,IO 多路復(fù)用的改進(jìn)是不再主動(dòng)去查詢數(shù)據(jù)狀態(tài)是否準(zhǔn)備完成,而是等數(shù)據(jù)準(zhǔn)備好的通知,當(dāng)數(shù)據(jù)準(zhǔn)備完成之后,才會(huì)開始傳輸數(shù)據(jù)。

與 NIO 一樣,在數(shù)據(jù)的傳輸階段,當(dāng)前線程依然是阻塞的。

在 Linux 系統(tǒng)中,IO 多路復(fù)用的方式有多種:

select

poll

epoll

信號(hào)驅(qū)動(dòng) IO

信號(hào)驅(qū)動(dòng) IO 通過 sigaction 系統(tǒng)調(diào)用,向內(nèi)核發(fā)送一個(gè)信號(hào),當(dāng)內(nèi)核中數(shù)據(jù)準(zhǔn)備好之后,當(dāng)前線程也會(huì)接收到一個(gè)信號(hào),在這個(gè)過程中,當(dāng)前線程也是非阻塞的。在接收到信號(hào)之后,就可以開始傳輸數(shù)據(jù)。

AIO

上面的這些 IO 模型雖然有些號(hào)稱是不阻塞的,那是指在等待數(shù)據(jù)就緒的過程中是不阻塞的,但是在接收數(shù)據(jù)的時(shí)候,依然還是阻塞的。

AIO 是這些 IO 模型中真正實(shí)現(xiàn)完全不阻塞,AIO 在被調(diào)用之后直接返回,連接收數(shù)據(jù)的階段也是非阻塞的,等到數(shù)據(jù)接收完成之后,內(nèi)核才會(huì)返回一個(gè)通知,也就是說當(dāng)用戶進(jìn)程接收到通知時(shí),數(shù)據(jù)已經(jīng)接收完成。

在 Linux 中提供了 AIO 的實(shí)現(xiàn),但是實(shí)際上使用的并不多,更多還是使用獨(dú)立的異步 IO 庫,比如libevent、libev、libuv。

五種 IO 模式的總結(jié)如下:

Java 中 IO 的實(shí)現(xiàn)

Java 中的 IO 也不例外,實(shí)際的 IO 是調(diào)用了系統(tǒng)的能力來完成,在用戶態(tài)通過系統(tǒng)調(diào)轉(zhuǎn)到內(nèi)核態(tài),最終實(shí)現(xiàn)文件的讀寫或者通信。

Java 中 IO 就是典型的 BIO,而且 NIO 則不是對(duì)應(yīng)五種 IO 模型中的 NIO,Java 中的 NIO 實(shí)際上是使用 IO 多路復(fù)用來實(shí)現(xiàn)的。

Java 中的 NIO2 也稱之為 AIO,正是對(duì)應(yīng)操作系統(tǒng)中的 AIO,當(dāng)然具體的實(shí)現(xiàn)可能是其他的庫。

文 / Rayjun

REF

[1] Unix 網(wǎng)絡(luò)編程

總結(jié)

以上是生活随笔為你收集整理的java中的io复用_从 Java 中的零拷贝到五种IO模型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。