日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Java NIO的多路復(fù)用及reactor

Java NIO從1.4版本就出現(xiàn)了,而且依它優(yōu)異的性能贏得了廣大java開發(fā)愛好者的信賴。我很納悶,為啥我到現(xiàn)在才接觸,難道我不是愛好者,難道nio不優(yōu)秀。經(jīng)過長(zhǎng)達(dá)半分鐘的思考,我意識(shí)到:時(shí)候未到。以前總是寫那些老掉牙的web程序,唉,好不容易翻身啦,現(xiàn)在心里好受多了。因?yàn)檎娌幌胱约旱搅?0歲,還在說,我會(huì)ssh,會(huì)ssi,精通javascript,精通數(shù)據(jù)庫,精通。。。人生苦短,要開拓點(diǎn)不是嗎?列為兄弟姐妹,沒看到外國的和尚已經(jīng)開始鼓吹“云里霧里”的?沒看到百度進(jìn)入“框”啦,沒看到oracle的“格”啦。人家的經(jīng),隨他念,但是我們的確有好多路要走哦(牢騷怎么這么多呀)。

現(xiàn)在終于到了我了解nio的時(shí)候了,突然發(fā)現(xiàn)有很多美妙程序的源碼,不得不爽一把(有邪念者,該打住啦,像我這樣)。

以下描述,為了說明問題,就提提歷史(類似的東西,網(wǎng)上一搜一大把,但是希望你能在這里止步,知道到底是怎么回事。如果還是不清楚,咱就站內(nèi)溝通?。?。

在我(剛)看nio的這段時(shí)間里,主要接觸了幾個(gè)東西,就是關(guān)于server和client。java之前的io完全可以勝任,但是效率不高,為何效率不高呢?

===============history==start===============
//TODO:finish the old style of server and socket data transion.
ServerSocket socket = new ServerSocket(80); 
while (true) { 
final Socket connection = socket.accept(); 
handleRequest(connection); 
}
===============history==end in the future================

在上面的代碼片段中,我們只能是一個(gè)request一個(gè)的進(jìn)行處理。這使得所有的請(qǐng)求都阻塞了。如果我們?cè)俑淖円幌?,將handleRequest方法封裝到線程中處理:

 
 
 
 
  1. if(connection = null){ 
  2. new Thread(new Runnable(){ 
  3. public void run(){ 
  4. handleRequest(connection); 
  5. public void handleRequest(Socket conn){ 
  6. //do actions 
  7. }).start(); 

服務(wù)器端的資源是有限的,我們這里僅僅是從線程角度來擴(kuò)展,但是這種處理依然是阻塞的處理方式。首先,僅僅是建立連接(socket),就占用了服務(wù)器的線程資源。如果客戶端還沒有發(fā)出相應(yīng)的數(shù)據(jù)請(qǐng)求,那么服務(wù)器就要一直等待他們的數(shù)據(jù)流過來,然后再進(jìn)行讀取,如此往復(fù)。。。一直都blocking。服務(wù)器處在一個(gè)高負(fù)荷狀態(tài)中。

NIO出來之后,進(jìn)入改革開放時(shí)期,有了這么幾個(gè)角色,ServerSocketChannel,SelectionKey,Selector。

這幾個(gè)角色都是做什么用的呢?需要了解一下reactor模式(反應(yīng)堆模式)。

作為服務(wù)端,如果什么操作都要依賴于客戶端,很多操作都阻塞,如上面的代碼片段所示。reactor模式提供了一種很好的事件處理機(jī)制,以分離事件處理對(duì)象與事件之間的耦合。如下圖示(詳細(xì)請(qǐng)看參考資料(1)):

說明:

Acceptor就是我們Server端的主要任務(wù)消化者;

Initiation Dispatcher是事件(Event)的分發(fā)者;

HTTP Handler是具體操作人。

首先,在Initiation Dispatcher中注冊(cè)一個(gè)acceptor(1:register Acceptor),這個(gè)Acceptor是跟事件綁定的,它僅僅關(guān)心某種事件(event)。

Initiation Dispatcher不斷地循環(huán)獲取請(qǐng)求過來的事件(2:handle events),如果發(fā)現(xiàn)有對(duì)應(yīng)Acceptor關(guān)心的事件(3:connect),通知Acceptor有事件發(fā)生(4:new connection)。

Acceptor針對(duì)此事件進(jìn)行處理,創(chuàng)建了新的HTTP Handler((5:create handler))

一輪事件獲取和分發(fā)完成。

那么handler是不是就抓住這個(gè)connection不放,然后一直苦苦等待數(shù)據(jù)流的到來呢?

不是的,它也是將自己和自己關(guān)心的事件注冊(cè)到Initiation Dispatcher。如果Initiation Dispatcher在handle Events時(shí)發(fā)現(xiàn)了它關(guān)心的事件,那么就會(huì)交由它去進(jìn)行相應(yīng)處理。如下圖示,在連接完成后,browser提交的get請(qǐng)求,handler的處理過程:

這里面尤其要注意到,2:read ready,之后才read request,也就是說,handler在dispatcher中注冊(cè)了自己關(guān)心的事件(READ),然后在寫的時(shí)候,也是類似情況。

以上的過程就實(shí)現(xiàn)了非阻塞的處理方式,客戶端的連接可以非阻塞(這是意思是,acceptor不必一直苦苦等候),然后對(duì)客戶端過來的request內(nèi)容,也是非阻塞(這里是不必苦苦等待其數(shù)據(jù)的到來),都是不必一直眼巴巴的看著那個(gè)連接,那些數(shù)據(jù),而是如果有我關(guān)心的事件了,我再進(jìn)行處理,期間完全相信Initiation Dispatcher就行了。

這里有一點(diǎn)要注意,就是現(xiàn)在的reactor模式都是建立在操作系統(tǒng)的基礎(chǔ)上實(shí)現(xiàn)的,不同的操作系統(tǒng)有不同的實(shí)現(xiàn)方式。而且都不支持多線程(針對(duì)Initiation Dispatcher而言)。

有了上面的理解之后,來給NIO中的對(duì)象跟reactor的對(duì)象對(duì)個(gè)象。

Acceptor:ServerSocketChannel;

Initiation Dispatcher:Selector;

HTTP Handler:針對(duì)SocketChannel進(jìn)行實(shí)際處理的個(gè)性化對(duì)象;

Events:在SelectionKey中:

static intOP_ACCEPT
          Operation-set bit for socket-accept operations.
static intOP_CONNECT
          Operation-set bit for socket-connect operations.
static intOP_READ
          Operation-set bit for read operations.
static intOP_WRITE
          Operation-set bit for write operations.

Operation-set bit for write operations. 經(jīng)過上面的描述,我們就可以寫出基于NIO的非阻塞Server啦。具體的代碼示例大家可以看參考資料(2)。

下一篇,NIO包中對(duì)象的介紹。有些本末倒置哦,但是,這篇里面沒有用到很多api,主要是reactor明白了,非阻塞明白了,目的就達(dá)到了。

參考資料:

(1)華盛頓大學(xué)計(jì)算機(jī)科學(xué)的一篇關(guān)于proactor的論文,非常詳細(xì)。同時(shí)這篇文章中還有 reactor的改進(jìn)版proactor,各位可以一飽眼福。

(2)簡(jiǎn)單的NIO server實(shí)現(xiàn)代碼,但是這個(gè)代碼中在寫的部分有些瑕疵,各位根據(jù)上面的描述,可以考慮一下有何問題。

在這個(gè)代碼中,還有一個(gè)要注意的地方,就it.remove(),因?yàn)槟硞€(gè)key在處理過后要?jiǎng)h除,否則,這個(gè)key將一直處于active狀態(tài)。


標(biāo)題名稱:Java NIO的多路復(fù)用及reactor
鏈接分享:http://www.dlmjj.cn/article/dhpsjed.html