国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java 網絡 IO 模型

Loong_T / 779人閱讀

摘要:有一個神奇的特性當發起操作之后,線程不用等待讀取完畢,而是可以直接返回,繼續執行其他操作。如果使用,一個線程可以同時發起多個操作,這就意味著,一個線程可以同時處理多個請求。

在進入主題之前先看個 Java 網絡編程的一個簡單例子:代碼很簡單,客戶端和服務端進行通信,對于客戶端的每次輸入,服務端回復 get。注意,服務端可以同時允許多個客戶端連接。

服務端端代碼:

// 創建服務端 socket
ServerSocket serverSocket = new ServerSocket(20000);
client = serverSocket.accept();

// 客戶端連接成功,輸出提示
System.out.println("客戶端連接成功");
// 啟動一個新的線程處理客戶端請求
new Thread(new ServerThread(client)).start();


// 子線程中處理客戶端的輸入
class ServerThread implements Runnable {
    .....
    @Override
    public void run() {
        boolean flag = true;
        while (flag) {

            // 讀取客戶端發送來的數據
            String str = buf.readLine();
            
            // 回復給客戶端 get 表示收到數據
            out.println("get"); 
        }
    }
}

客戶端代碼 :

Socket client = new Socket("127.0.0.1", 20000);
boolean flag = true;
while (flag) {
    
    // 讀取用戶從鍵盤的輸入
    String str = input.readLine();
    // 把用戶的輸入發送給服務端
    out.println(str);

    // 接受到服務端回傳的 get 字符串
    String echo = buf.readLine();
    System.out.println(echo);
    }
}

考慮到完整的 Java 示例代碼太過龐大影響閱讀,所以這里不完整貼出,如果需要在 github 直接下載,這里是下載地址。

可以看到,server 為了能夠同時處理多個 client 的請求,需要為每個 client 開啟一個 thread,這種 one-thread-per-client 的模式對于 server 而言壓力是很大的。假設有 1k 個 client,對應的 server 應該啟動 1k 個 thread,那么 server 所耗費的內存,以及 thread 切換時候占用的時間等等都是致命傷。即使使用線程池的技術來限制線程個數,這種 blocking-IO 的模型還是沒辦法支撐大量連接。

每個 client 都需要一個 thread 來請求處理。

NIO

上面這種 one-thread-per-client 的模式無法支撐大量連接的主要原因在于 readLine阻塞 IO,即在 readLine 沒能夠讀取到數據的時候,會一直阻塞線程,使得線程無法繼續執行,那么 server 為了可以同時處理多個 client,只能同時開啟多個線程。

所以,Java 1.4 之后引入了一套 NIO 接口。NIO 中最主要的一個功能就是可以進行非阻塞 IO 操作:如果沒能夠讀取到數據,非阻塞 IO 不會阻塞線程,而是直接返回 0。這種情況下,線程通過返回值判斷數據還沒有準備好,就可以處理其他事情,而不會被阻塞。

上圖是阻塞 IO 和非阻塞 IO 的區別,可以看出雖然 非阻塞 IO 并不會被阻塞,但是它仍然不斷的調用函數檢查數據是否已經可讀,這種現象在代碼中是以這種形式展現:

while((str = read()) == 0) {
   
}
 // 繼續讀取到數據之后的邏輯。

可以明白,雖然非阻塞 IO 不會阻塞線程,但是由于沒有數據可讀,線程也沒有辦法繼續執行下面的邏輯,只能不斷的調用判斷,等待數據到來。這種情況下稱為同步 IO。所以綜上,NIO 本質上是一個非阻塞同步 IO。

IO 復用

由于 NIO 不會因為數據還沒有到達而被阻塞,那么就沒有必要每一個 client 都分配一個 thread 不斷去輪詢判斷是否有數據可讀??梢允褂靡粋€ thread 監聽所有的 client 連接,由這個 thread 循環判斷是否有某個 client 的數據可讀,如果有就告知其他 thread 某個 client 連接由數據可讀。這種行為就被稱之為 IO 復用。 在 NIO 中提供了 Selector 類來監聽所有 client 連接是否有數據可讀。

使用 Selector 來實現 IO 復用,只有一個 thread 需要關心數據是否到來,其他線程等待通知就好。如此一來,只有監聽線程會一直循環判斷,并不會占據太多 CPU 資源。提到 NIO 中的 Selector,不得不說一下 Linux 編程中的 IO 復用,因為 NIO 中的 Selector 底層就是使用系統級的 IO 復用方案。

Linux 系統的 IO 復用實現方案有 2 種:

select

epoll

在 Linux 2.6+ 的版本上 NIO 底層使用的是 epoll,在 2.4.x 的版本使用的是 select 函數。epoll 函數在性能方面比 select 好很多,這里可以不關心 Linux 編程具體細節。值得一提的是,Java 的 netty 網絡框架底層就是使用 NIO 技術。

AIO

回顧一下 NIO 中:使用監聽線程調用 select 函數來監聽所有請求是否有數據到達,如果有數據則通知其他線程來讀取數據。這里在線程讀取數據的過程中,線程在數據沒有讀取完畢之前是處于阻塞狀態,只有數據讀取完畢之后線程才可以繼續執行邏輯。之前說過,這種稱之為同步 IO。JDK 7 中新增了一套新接口 AIO(Asynchronous IO)。

AIO 有一個神奇的特性:當發起 IO 操作之后,線程不用等待 IO 讀取完畢,而是可以直接返回,繼續執行其他操作。等到數據讀取完畢之后,系統會通知線程數據已經讀取完畢。這種發起 IO 操作,但是不必等待數據讀取完畢的 IO 操作稱之為異步 IO。如果使用 AIO,一個線程可以同時發起多個 IO 操作,這就意味著,一個線程可以同時處理多個請求。著名的 web 服務器 Nginx 就是用了異步 IO。關于更多的細節,可以參考下我的另一篇文章 End

到目前為止,文章解釋了阻塞/非阻塞 IO,同步/異步 IO 的區別,談起 IO 模型,不可避免會涉及 Linux 的 5 種 IO 模型

阻塞 IO

非阻塞 IO

IO 復用

信號驅動 IO

異步 IO

除去信號驅動 IO沒有提及,其他 4 種主要的 IO 模型都有所解釋,理解了這些 IO 模型的概念對于編寫代碼有很大的幫助。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70605.html

相關文章

  • java同步非阻塞IO

    摘要:的異步即是異步的,也是非阻塞的。但是,也可以進行一層稍微薄點的封裝,保留這種多路復用的模型,比如的,是一種同步非阻塞的模型。系統調用操作系統的系統調用提供了多路復用的非阻塞的系統調用,這也是機制實現需要用到的。 異步IO編程在javascript中得到了廣泛的應用,之前也寫過一篇博文進行梳理。js的異步IO即是異步的,也是非阻塞的。非阻塞的IO需要底層操作系統的支持,比如在linux上...

    caoym 評論0 收藏0
  • JDK10都發布了,nio你了解多少?

    摘要:而我們現在都已經發布了,的都不知道,這有點說不過去了。而對一個的讀寫也會有響應的描述符,稱為文件描述符,描述符就是一個數字,指向內核中的一個結構體文件路徑,數據區等一些屬性。 前言 只有光頭才能變強 回顧前面: 給女朋友講解什么是代理模式 包裝模式就是這么簡單啦 本來我預想是先來回顧一下傳統的IO模式的,將傳統的IO模式的相關類理清楚(因為IO的類很多)。 但是,發現在整理的過程已...

    YFan 評論0 收藏0
  • Java NIO淺析

    摘要:阻塞請求結果返回之前,當前線程被掛起。也就是說在異步中,不會對用戶線程產生任何阻塞。當前線程在拿到此次請求結果的過程中,可以做其它事情。事實上,可以只用一個線程處理所有的通道。 準備知識 同步、異步、阻塞、非阻塞 同步和異步說的是服務端消息的通知機制,阻塞和非阻塞說的是客戶端線程的狀態。已客戶端一次網絡請求為例做簡單說明: 同步同步是指一次請求沒有得到結果之前就不返回。 異步請求不會...

    yeooo 評論0 收藏0
  • Java網絡編程-你是GG還是MM?

    摘要:網絡層主要將從下層接收到的數據進行地址例的封裝與解封裝。會話層通過傳輸層端口號傳輸端口與接收端口建立數據傳輸的通路。 第六階段 網絡編程 每一臺計算機通過網絡連接起來,達到了數據互動的效果,而網絡編程所解決的問題就是如何讓程序與程序之間實現數據的通訊與互動在嗎?你是GG還是MM? (一) 網絡模型概述 (1) 兩大模型 網絡模型一般是指: OSI(Open System Inter...

    Shihira 評論0 收藏0
  • NIO網絡相關基礎知識

    摘要:操作系統是能夠獲取到事件操作完成的事件,基于回調函數機制和操作系統的操作控制實現事件檢測機制。 前面的文章NIO基礎知識介紹了Java NIO的一些基本的類及功能說明,Java NIO是用來替換java 傳統IO的,NIO的一些新的特性在網絡交互方面會更加的明顯。 Java 傳統IO的弊端 ????基于JVM來實現每個通道的輪詢檢查通道狀態的方法是可行的,但仍然是有問題的,檢查每個通道...

    1fe1se 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<