首頁 Java java教程 常見JAVA中IO/NIO模型

常見JAVA中IO/NIO模型

Aug 23, 2019 pm 03:39 PM
java

我們常見的IO模型有:阻塞 IO 模型、非阻塞 IO 模型、多路復用 IO 模型、 訊號驅動 IO 模型、異步 IO 模型;以下我們簡單介紹以上IO模型。

常見JAVA中IO/NIO模型

1、阻塞IO 模型

#最傳統的IO 模型,也就是讀寫資料過程中會發生阻塞現象。當用戶執行緒發出IO 請求之後,核心會去查看資料是否就緒,如果沒有就緒就會等待資料就緒,而用戶執行緒就會處於阻塞狀態,用戶執行緒交出CPU。當資料就緒之後,核心會將資料拷貝到使用者線程,並傳回結果給使用者線程,使用者線程才會解除block 狀態。典型的阻塞IO 模型的範例為:data = socket.read();如果資料沒有就緒,就會一直阻塞在read 方法。

2、非阻塞 IO 模型

當使用者執行緒啟動一個read 操作後,並不需要等待,而是馬上就得到了一個結果。如果結果是一個error 時,它就知道資料還沒準備好,於是它可以再次傳送read 操作。一旦核心中的資料準備好了,並且又再次收到了用戶線程的請求,那麼它馬上就將資料拷貝到了用戶線程,然後返回。所以事實上,在非阻塞IO 模型中,使用者執行緒需要不斷詢問核心資料是否就緒,也就說非阻塞IO不會交出CPU,而會一直佔用CPU。典型的非阻塞IO 模型一般如下:

while(true){
        data = socket.read();
        if(data!= error){
        处理数据
        break;
    }
}
登入後複製

但是對於非阻塞IO 就有一個非常嚴重的問題,在while 循環中需要不斷地去詢問內核資料是否就緒,這樣會導致CPU 佔用率非常高,因此一般情況下很少使用while 迴圈這種方式來讀取資料。

3、多路復用 IO 模型

多路復用IO 模型是目前使用得比較多的模型。

Java NIO 其實就是多路復用IO。在多路復用IO模型中,會有一個執行緒不斷去輪詢多個socket 的狀態,只有當socket 真正有讀寫事件時,才真正呼叫實際的IO 讀寫操作。

因為在多路復用IO 模型中,只需要使用一個線程就可以管理多個socket,系統不需要建立新的進程或線程,也不必維護這些線程和進程,並且只有在真正有socket 讀寫事件進行時,才會使用IO 資源,所以它大大減少了資源佔用。

在Java NIO 中,是透過selector.select()去查詢每個通道是否有到達事件,如果沒有事件,則一直阻塞在那裡,因此這種方式會導致使用者執行緒的阻塞。

多路復用IO 模式,透過一個執行緒就可以管理多個socket,只有當socket 真正有讀寫事件發生才會佔用資源來進行實際的讀寫操作。因此,多路復用IO 比較適合連接數比較多的情況。

另外多路復用IO 為何比非阻塞IO 模型的效率高是因為在非阻塞IO 中,不斷地詢問socket 狀態時透過使用者執行緒去進行的,而在多路復用IO 中,輪詢每個socket 狀態是核心在進行的,這個效率要比使用者執行緒要高的多。

不過要注意的是,多路復用IO 模型是透過輪詢的方式來偵測是否有事件到達,並且對到達的事件逐一回應。因此對於多路復用IO 模型來說,一旦事件回應體很大,那麼就會導致後續的事件遲遲無法處理,並且會影響新的事件輪詢。

4、訊號驅動IO 模型

在訊號驅動IO 模型中,當使用者執行緒發起一個IO 請求操作,會給對應的socket 註冊一個訊號函數,接著使用者執行緒會繼續執行,當核心資料就緒時會傳送一個訊號給使用者線程,使用者執行緒接收到訊號之後,便在訊號函數中呼叫IO 讀寫操作來進行實際的IO 請求操作。

5、非同步IO 模型

非同步IO 模型才是最理想的IO 模型,在非同步IO 模型中,當使用者執行緒發起read 操作之後,立刻就可以開始去做其它的事。

而另一方面,從核心的角度,當它受到一個asynchronous read 之後,它會立刻返回,說明read 請求已經成功發起了,因此不會對用戶線程產生任何block。

然後,核心會等待資料準備完成,然後將資料拷貝到使用者線程,當這一切都完成之後,核心會給使用者線程發送一個訊號,告訴它read 操作完成了。也就說使用者執行緒完全不需要實際的整個IO 操作是如何進行的,只需要先發起一個請求,當接收核心回傳的成功訊號時表示IO 操作已經完成,可以直接去使用資料了。

也就說在非同步IO 模型中,IO 操作的兩個階段都不會阻塞使用者線程,這兩個階段都是由核心自動完成,然後發送一個訊號告知使用者線程操作已完成。使用者執行緒中不需要再次呼叫IO 函數進行具體的讀寫。

這點是和訊號驅動模型有所不同的,在訊號驅動模型中,當使用者執行緒接收到訊號表示資料已經就緒,然後需要使用者執行緒呼叫IO 函數進行實際的讀寫操作;而在異步IO模型中,收到訊號表示IO 操作已經完成,不需要再在使用者執行緒中呼叫IO 函數進行實際的讀寫操作。

注意,非同步IO 是需要作業系統的底層支持,在Java 7 中,提供了Asynchronous IO。

以上是常見JAVA中IO/NIO模型的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Java 中的完美數 Java 中的完美數 Aug 30, 2024 pm 04:28 PM

Java 完美數指南。這裡我們討論定義,如何在 Java 中檢查完美數?

Java 中的隨機數產生器 Java 中的隨機數產生器 Aug 30, 2024 pm 04:27 PM

Java 隨機數產生器指南。在這裡,我們透過範例討論 Java 中的函數,並透過範例討論兩個不同的生成器。

Java中的Weka Java中的Weka Aug 30, 2024 pm 04:28 PM

Java 版 Weka 指南。這裡我們透過範例討論簡介、如何使用 weka java、平台類型和優點。

Java 中的史密斯數 Java 中的史密斯數 Aug 30, 2024 pm 04:28 PM

Java 史密斯數指南。這裡我們討論定義,如何在Java中檢查史密斯號?帶有程式碼實現的範例。

Java Spring 面試題 Java Spring 面試題 Aug 30, 2024 pm 04:29 PM

在本文中,我們保留了最常被問到的 Java Spring 面試問題及其詳細答案。這樣你就可以順利通過面試。

突破或從Java 8流返回? 突破或從Java 8流返回? Feb 07, 2025 pm 12:09 PM

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

Java 中的時間戳至今 Java 中的時間戳至今 Aug 30, 2024 pm 04:28 PM

Java 中的時間戳記到日期指南。這裡我們也結合範例討論了介紹以及如何在java中將時間戳記轉換為日期。

Java程序查找膠囊的體積 Java程序查找膠囊的體積 Feb 07, 2025 am 11:37 AM

膠囊是一種三維幾何圖形,由一個圓柱體和兩端各一個半球體組成。膠囊的體積可以通過將圓柱體的體積和兩端半球體的體積相加來計算。本教程將討論如何使用不同的方法在Java中計算給定膠囊的體積。 膠囊體積公式 膠囊體積的公式如下: 膠囊體積 = 圓柱體體積 兩個半球體體積 其中, r: 半球體的半徑。 h: 圓柱體的高度(不包括半球體)。 例子 1 輸入 半徑 = 5 單位 高度 = 10 單位 輸出 體積 = 1570.8 立方單位 解釋 使用公式計算體積: 體積 = π × r2 × h (4

See all articles