成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

NIO網(wǎng)絡(luò)相關(guān)基礎(chǔ)知識(shí)

1fe1se / 2811人閱讀

摘要:操作系統(tǒng)是能夠獲取到事件操作完成的事件,基于回調(diào)函數(shù)機(jī)制和操作系統(tǒng)的操作控制實(shí)現(xiàn)事件檢測(cè)機(jī)制。

前面的文章NIO基礎(chǔ)知識(shí)介紹了Java NIO的一些基本的類及功能說明,Java NIO是用來替換java 傳統(tǒng)IO的,NIO的一些新的特性在網(wǎng)絡(luò)交互方面會(huì)更加的明顯。

Java 傳統(tǒng)IO的弊端

????“基于JVM來實(shí)現(xiàn)每個(gè)通道的輪詢檢查通道狀態(tài)的方法是可行的,但仍然是有問題的,檢查每個(gè)通道是否就緒是至少需要一次系統(tǒng)調(diào)用,執(zhí)行的代價(jià)是非常昂貴的。同時(shí)這種檢查不是原子的。列表中的每個(gè)通道在檢查之后狀態(tài)變成就緒,但需要等到下一次輪詢之前JVM是無法感知的。最糟糕的是,JVM除了不斷遍歷列表之外將別無選擇。JVM無法在某通道就緒時(shí)直接得到通知。
????這就是為什么監(jiān)控多個(gè)socket連接的傳統(tǒng)的java方案是:為每個(gè)socket創(chuàng)建一個(gè)線程并使線程可以再read()調(diào)用中阻塞,直到數(shù)據(jù)可用。這實(shí)際上將每個(gè)阻塞在對(duì)應(yīng)socket上的線程當(dāng)做了socket事件監(jiān)控器,并將JVM的線程調(diào)度當(dāng)做了事件通知。但是線程的阻塞和JVM的線程調(diào)用都是為了這種目的而設(shè)計(jì)的。當(dāng)線程數(shù)量增長失控時(shí),JVM為了管理這些線程,導(dǎo)致程序性能降低?!?em>--摘自《JAVA NIO》
上述兩段話摘自《JAVA NIO》第四章-選擇器中,主要闡述了java 傳統(tǒng)NIO的基本實(shí)現(xiàn)和弊端。通過上述文字我們也知道了,提高傳統(tǒng)IO的性能可以從兩方面入手:1.減少線程數(shù)量 2.實(shí)時(shí)獲取IO事件。

I/O模型

傳統(tǒng)I/O為了能實(shí)時(shí)獲取I/O事件,所以才會(huì)給每個(gè)socket連接分配一個(gè)線程用于監(jiān)控socket事件,因?yàn)槿绾潍@取I/O事件通知是關(guān)鍵。因此調(diào)整JVM的I/O模型是提高I/O性能關(guān)鍵。
我們來了解下I/O模型的類型:

單線程阻塞I/O模型

只能同時(shí)處理一個(gè)客戶端請(qǐng)求,并且在I/O操作上是阻塞的,服務(wù)端線程會(huì)一直等待I/O操作完成,不會(huì)做其他的事情。服務(wù)端讀取客戶端數(shù)據(jù)時(shí)要等待客戶端發(fā)送數(shù)據(jù)并且操作系統(tǒng)內(nèi)核復(fù)制到用戶進(jìn)程中之后才解除阻塞狀態(tài);服務(wù)端寫數(shù)據(jù)回客戶端是要等待用戶進(jìn)程將數(shù)據(jù)寫入內(nèi)核并發(fā)送到客戶端后才解除阻塞狀態(tài)。單線程阻塞I/O模型無法同時(shí)處理多個(gè)連接,只能串行處理連接。整個(gè)運(yùn)行過程都只有一個(gè)線程,服務(wù)端系統(tǒng)資源消耗較小,但并發(fā)能力低。

多線程阻塞I/O模型

利用多線程機(jī)制為每個(gè)客戶端分配一個(gè)線程,每個(gè)線程執(zhí)行讀取客戶端的數(shù)據(jù)或數(shù)據(jù)成功寫入客戶端后才解除阻塞狀態(tài)。支持多個(gè)客戶端并發(fā)響應(yīng),處理能力得到提高。系統(tǒng)資源消耗較大,多線程之間會(huì)產(chǎn)生線程切換成本,同時(shí)為了實(shí)現(xiàn)線程安全引入線程同步機(jī)制導(dǎo)成程序結(jié)構(gòu)復(fù)雜。

單線程非阻塞I/O模型

在調(diào)用讀寫接口后立即返回,而不會(huì)進(jìn)入阻塞狀態(tài);基于事件檢測(cè)機(jī)制獲取到事件發(fā)生,進(jìn)行對(duì)應(yīng)事件的I/O操作。
事件檢測(cè)方式:

應(yīng)用程序遍歷套接字的事件檢測(cè)

服務(wù)端程序會(huì)保存一個(gè)socket套接字連接列表,應(yīng)用層線程對(duì)socket套接字列表輪詢嘗試讀取或?qū)懭搿H绻麌L試失敗,則在下一個(gè)循環(huán)再繼續(xù)嘗試。查詢每個(gè)socket套接字都至少需要一次系統(tǒng)調(diào)用,而且無法立即獲取socket套接字狀態(tài)。同時(shí)應(yīng)用程序除了要遍歷socket套接字列表之外,還需要處理數(shù)據(jù)的拼接,實(shí)際會(huì)占用較多的CPU資源

內(nèi)核遍歷套接字的事件檢測(cè)

將遍歷socket列表的工作交給操作系統(tǒng)內(nèi)核,應(yīng)用層向發(fā)去操作系統(tǒng)內(nèi)核請(qǐng)求讀寫列表。操作系統(tǒng)內(nèi)核會(huì)遍歷所有套接字并生成對(duì)應(yīng)的可讀列表readList和可寫列表writeList返回給應(yīng)用程序。應(yīng)用程序獲取到具體socket,對(duì)每個(gè)socket進(jìn)行相應(yīng)的I/O操作。
應(yīng)用程序向內(nèi)核請(qǐng)求讀寫列表,內(nèi)核遍歷所有的套接字并生成對(duì)應(yīng)的可讀列表readList和可寫列表writeList。readList標(biāo)明了每個(gè)套接字是否可讀,例如套接字2、套接字3的值為1表示可讀,套接字1的值為0表示不可讀;同樣,writeList表示套接字是否可寫。

內(nèi)核基于事件回調(diào)的事件檢測(cè)

遍歷套接字列表是個(gè)效率比較低的方式,無論是在內(nèi)核層還是在應(yīng)用層。操作系統(tǒng)是能夠獲取到I/O事件操作完成的事件,基于回調(diào)函數(shù)機(jī)制和操作系統(tǒng)的I/O操作控制實(shí)現(xiàn)事件檢測(cè)機(jī)制。

基于回調(diào)機(jī)制的完全套接字可讀可寫列表

用可讀列表readList和可寫列表writeList標(biāo)記讀寫事件,套接字的數(shù)量與readList和writeList兩個(gè)列表的長度一樣。readList元素為1表示可讀,writeList元素為1表示可寫。當(dāng)客戶端發(fā)送數(shù)據(jù)到服務(wù)端,內(nèi)核完成從網(wǎng)卡復(fù)制數(shù)據(jù)調(diào)用回調(diào)函數(shù)將對(duì)應(yīng)套接字readList中的元素置為1;若套接字已經(jīng)做好寫操作準(zhǔn)備,內(nèi)核會(huì)將套接字對(duì)應(yīng)writeList中的元素置為1。應(yīng)用程序發(fā)送請(qǐng)求讀、寫事件列表,內(nèi)核會(huì)把包含readList和writeList的事件列表返回給應(yīng)用程序,應(yīng)用程序分別遍歷列表,進(jìn)而記性讀寫操作。

基于回調(diào)機(jī)制的部分套接字事件列表

如果套接字?jǐn)?shù)量變大,事件列表傳輸也是不小的開銷。可以讓應(yīng)用層告訴內(nèi)核每個(gè)套接字感興趣的事件,當(dāng)客戶端發(fā)送數(shù)據(jù)過來時(shí),內(nèi)核完成從網(wǎng)卡復(fù)制后即調(diào)用回調(diào)函數(shù)將套接字相關(guān)信息封裝成可讀事件event放到事件列表中;同樣,內(nèi)核發(fā)現(xiàn)網(wǎng)卡可寫時(shí)會(huì)將套接字相關(guān)信息封裝成可寫事件event添加到事件列表中,事件列表中只有處于ready狀態(tài)的那部分套接字對(duì)應(yīng)的事件。java NIO即是采用這種事件檢測(cè)機(jī)制,在客戶端連接大多數(shù)處于活躍的情況下,服務(wù)端只用一個(gè)線程一直循環(huán)處理這些連接,很好地利用了I/O操作的阻塞時(shí)間,提高了線程執(zhí)行效率。

多線程非阻塞I/O模型

單線程非阻塞I/O已經(jīng)大大提高了機(jī)器的執(zhí)行效率,在多核機(jī)器上為了更好的提高CPU的使用率可以引入多線程。引入reactor線程模型,每個(gè)線程處理不同類型的事件連接。

NIO網(wǎng)絡(luò)通信

java NIO性能較java傳統(tǒng)IO有較大提升主要是在網(wǎng)絡(luò)交互中,通過Selector來管理客戶端的連接,應(yīng)用程序?qū)⒖蛻舳藄ocket連接注冊(cè)到Selector對(duì)象上。當(dāng)客戶端socket連接有數(shù)據(jù)準(zhǔn)備就緒或連接準(zhǔn)備好寫操作時(shí),應(yīng)用程序通過selector獲取到對(duì)應(yīng)socket通道(Channel),應(yīng)用程序通過Channel對(duì)socket進(jìn)行讀寫操作。
NIO中服務(wù)端一個(gè)線程可以同時(shí)與多個(gè)客戶端連接進(jìn)行讀寫交互;而傳統(tǒng)IO則是服務(wù)端的一個(gè)線程只能同時(shí)處理一個(gè)客戶端,I/O操作時(shí),線程處于阻塞狀態(tài)。
Selector是SelectableChannel的多路復(fù)用選擇器,用于監(jiān)控SelectableChannel的IO狀況的。在Selector定義為SelectableChannel定義了四種事件類型:
SelectionKey.OP_READ????????讀事件
SelectionKey.OP_WRITE???????寫事件
SelectionKey.OP_CONNECT????接收到客戶端的連接事件
SelectionKey.OP_ACCEPT??????接收到客戶端的請(qǐng)求事件
多個(gè)事件之間用“|”連接
當(dāng)服務(wù)端線程注冊(cè)事件發(fā)生時(shí),操作系統(tǒng)內(nèi)核會(huì)通過回調(diào)函數(shù)將該事件放到讀寫事件列表中。JVM通過Selector的select方法會(huì)獲取到已經(jīng)注冊(cè)到Selector對(duì)象上的事件列表。若沒有事件發(fā)生select方法會(huì)一直阻塞知道有注冊(cè)的時(shí)間發(fā)生才會(huì)把發(fā)生的時(shí)間返回給Selector對(duì)象。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/68649.html

相關(guān)文章

  • JDK10都發(fā)布了,nio你了解多少?

    摘要:而我們現(xiàn)在都已經(jīng)發(fā)布了,的都不知道,這有點(diǎn)說不過去了。而對(duì)一個(gè)的讀寫也會(huì)有響應(yīng)的描述符,稱為文件描述符,描述符就是一個(gè)數(shù)字,指向內(nèi)核中的一個(gè)結(jié)構(gòu)體文件路徑,數(shù)據(jù)區(qū)等一些屬性。 前言 只有光頭才能變強(qiáng) 回顧前面: 給女朋友講解什么是代理模式 包裝模式就是這么簡單啦 本來我預(yù)想是先來回顧一下傳統(tǒng)的IO模式的,將傳統(tǒng)的IO模式的相關(guān)類理清楚(因?yàn)镮O的類很多)。 但是,發(fā)現(xiàn)在整理的過程已...

    YFan 評(píng)論0 收藏0
  • 準(zhǔn)備好了再通知我:網(wǎng)絡(luò)NIO

    摘要:當(dāng)?shù)臄?shù)據(jù)準(zhǔn)備好時(shí),就會(huì)接到通知,得到那些已經(jīng)準(zhǔn)備好的數(shù)據(jù)。當(dāng)與客戶端連接的數(shù)據(jù)沒有準(zhǔn)備好時(shí),會(huì)處于等待狀態(tài)不過幸好,用于管理的線程數(shù)是極少量的,而一旦有任何一個(gè)準(zhǔn)備好了數(shù)據(jù),就能立即得到通知,獲取數(shù)據(jù)進(jìn)行處理。 java NIO是NEW IO的簡稱,它是一種可以替代javaIO的一套新的IO機(jī)制。它提供了一套不同java標(biāo)準(zhǔn)IO的操作機(jī)制。嚴(yán)格來說,NIO與并發(fā)并無直接關(guān)系。但是,使用...

    gougoujiang 評(píng)論0 收藏0
  • I/O模型和Java NIO源碼分析

    摘要:最近在學(xué)習(xí)網(wǎng)絡(luò)編程和相關(guān)的知識(shí),了解到是模式的網(wǎng)絡(luò)框架,但是提供了不同的來支持不同模式的網(wǎng)絡(luò)通信處理,包括同步異步阻塞和非阻塞。因?yàn)榈陌姹臼褂玫牡哪J?,而則希望使用模式,而且版本沒有將的部分配置項(xiàng)暴露出來,比如說和。 ??最近在學(xué)習(xí)Java網(wǎng)絡(luò)編程和Netty相關(guān)的知識(shí),了解到Netty是NIO模式的網(wǎng)絡(luò)框架,但是提供了不同的Channel來支持不同模式的網(wǎng)絡(luò)通信處理,包括同步、異步、...

    yuanxin 評(píng)論0 收藏0
  • 少啰嗦!一分鐘帶你讀懂Java的NIO和經(jīng)典IO的區(qū)別

    摘要:的選擇器允許單個(gè)線程監(jiān)視多個(gè)輸入通道。一旦執(zhí)行的線程已經(jīng)超過讀取代碼中的某個(gè)數(shù)據(jù)片段,該線程就不會(huì)在數(shù)據(jù)中向后移動(dòng)通常不會(huì)。 1、引言 很多初涉網(wǎng)絡(luò)編程的程序員,在研究Java NIO(即異步IO)和經(jīng)典IO(也就是常說的阻塞式IO)的API時(shí),很快就會(huì)發(fā)現(xiàn)一個(gè)問題:我什么時(shí)候應(yīng)該使用經(jīng)典IO,什么時(shí)候應(yīng)該使用NIO? 在本文中,將嘗試用簡明扼要的文字,闡明Java NIO和經(jīng)典IO之...

    Meils 評(píng)論0 收藏0
  • 關(guān)于Java IO與NIO知識(shí)都在這里

    摘要:從通道進(jìn)行數(shù)據(jù)寫入創(chuàng)建一個(gè)緩沖區(qū),填充數(shù)據(jù),并要求通道寫入數(shù)據(jù)。三之通道主要內(nèi)容通道介紹通常來說中的所有都是從通道開始的。從中選擇選擇器維護(hù)注冊(cè)過的通道的集合,并且這種注冊(cè)關(guān)系都被封裝在當(dāng)中停止選擇的方法方法和方法。 由于內(nèi)容比較多,我下面放的一部分是我更新在我的微信公眾號(hào)上的鏈接,微信排版比較好看,更加利于閱讀。每一篇文章下面我都把文章的主要內(nèi)容給列出來了,便于大家學(xué)習(xí)與回顧。 Ja...

    Riddler 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<