久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      Java NIO類庫Selector機制解析(下)

      五、 迷惑不解 : 為什么要自己消耗資源?

      令人不解的是為什么我們的Java的New I/O要設(shè)計成這個樣子?如果說老的I/O不能多路復(fù)用,如下圖所示,要開N多的線程去挨個偵聽每一個Channel
      (文件描述符) ,如果這樣做很費資源,且效率不高的話。那為什么在新的I/O機制依然需要自己連接自己,而且,還是重復(fù)連接,消耗雙倍的資源?

      通過WEB搜索引擎沒有找到為什么。只看到N多的人在報BUG,但SUN卻沒有任何解釋。

      下面一個圖展示了,老的IO和新IO的在網(wǎng)絡(luò)編程方面的差別。看起來NIO的確很好很強大。但似乎比起C/C++來說,Java的這種實現(xiàn)會有一些不必要的開銷。

      六、 它山之石 : 從Apache的Mina框架了解Selector

      上面的調(diào)查沒過多長時間,正好同學(xué)趙錕的一個同事也在開發(fā)網(wǎng)絡(luò)程序,這位仁兄使用了Apache的Mina框架。當(dāng)我們把Mina框架的源碼研讀了一下后。發(fā)現(xiàn)在Mina中有這么一個機制:

      1)Mina框架會創(chuàng)建一個Work對象的線程。

      2)Work對象的線程的run()方法會從一個隊列中拿出一堆Channel,然后使用Selector.select()方法來偵聽是否有數(shù)據(jù)可以讀/寫。

      3)最關(guān)鍵的是,在select的時候,如果隊列有新的Channel加入,那么,Selector.select()會被喚醒,然后重新select最新的Channel集合。

      4)要喚醒select方法,只需要調(diào)用Selector的wakeup()方法。

      對于熟悉于系統(tǒng)調(diào)用的C/C++程序員來說,一個阻塞在select上的線程有以下三種方式可以被喚醒:

      1) 有數(shù)據(jù)可讀/寫,或出現(xiàn)異常。

      2) 阻塞時間到,即time out。

      3) 收到一個non-block的信號??捎蒶ill或pthread_kill發(fā)出。

      所以,Selector.wakeup()要喚醒阻塞的select,那么也只能通過這三種方法,其中:

      1)第二種方法可以排除,因為select一旦阻塞,應(yīng)無法修改其time out時間。

      2)而第三種看來只能在Linux上實現(xiàn),Windows上沒有這種信號通知的機制。

      所以,看來只有第一種方法了。再回想到為什么每個Selector.open(),在Windows會建立一對自己和自己的loopback的TCP連接;在Linux上會開一對pipe(pipe在Linux下一般都是成對打開),估計我們能夠猜得出來——那就是如果想要喚醒select,只需要朝著自己的這個loopback連接發(fā)點數(shù)據(jù)過去,于是,就可以喚醒阻塞在select上的線程了。

      七、 真相大白 : 可愛的Java你太不容易了

      使用Linux下的strace命令,我們可以方便地證明這一點。參看下圖。圖中,請注意下面幾點:

      1) 26654是主線程,之前我輸出notify the select字符串是為了做一個標(biāo)記,而不至于迷失在大量的strace log中。

      2) 26662是偵聽線程,也就是select阻塞的線程。

      3) 圖中選中的兩行。26654的write正是wakeup()方法的系統(tǒng)調(diào)用,而緊接著的就是26662的epoll_wait的返回。

      從上圖可見,這和我們之前的猜想正好一樣??梢?,JDK的Selector自己和自己建的那些TCP連接或是pipe,正是用來實現(xiàn)Selector的notify和wakeup的功能的。

      這兩個方法完全是來模仿Linux中的的kill和pthread_kill給阻塞在select上的線程發(fā)信號的。但因為發(fā)信號這個東西并不是一個跨平臺的標(biāo)準(zhǔn)(pthread_kill這個系統(tǒng)調(diào)用也不是所有Unix/Linux都支持的),而pipe是所有的Unix/Linux所支持的,但Windows又不支持,所以,Windows用了TCP連接來實現(xiàn)這個事。

      關(guān)于Windows,我一直在想,Windows的防火墻的設(shè)置是不是會讓Java的類似的程序執(zhí)行異常呢?呵呵。如果不知道Java的SDK有這樣的機制,誰知道會有多少個程序為此引起的問題度過多少個不眠之夜,尤其是Java程序員。

      八、 后記

      文章到這里是可以結(jié)束了,但關(guān)于Java NIO的Selector引出來的其它話題還有許多,比如關(guān)于GNU
      的Java編譯器又是如何,它是否會像Sun的Java解釋器如此做傻事?我在這里先賣一個關(guān)子,關(guān)于GNU的Java編譯器,我會在另外一篇文章中講述,近期發(fā)布,敬請期待。

      關(guān)于本文中所使用的實驗平臺如下:

      ◆  Windows:Windows XP + SP2, Sun J2SE (build 1.7.0-ea-b23)

      ◆  Linux:Ubuntu 7.10 + Linux Kernel 2.6.22-14-generic, J2SE (build
      1.6.0_03-b05)

      本文主要的調(diào)查工作由我的大學(xué)同學(xué)趙錕完成,我?guī)推潋炞C調(diào)查成果及猜想。在此也向大家介紹我的大學(xué)同學(xué)趙錕,他也是一個技術(shù)高手,在軟件開發(fā)方面,特別是Unix/Linux
      C/C++方面有著相當(dāng)?shù)墓Φ?,相信自此以后,會有很多文章會由我和他一同發(fā)布。

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號