<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    jclown

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      3 Posts :: 0 Stories :: 6 Comments :: 0 Trackbacks

    2010年10月1日 #

      Java nio從jdk1.4開始引入進來的。通常聽到比較多的說法是: 你還沒有用nio啊,你“out”啦;nio不阻塞,傳統(tǒng)的I/O都是阻塞的,效率很低...... 如果你的系統(tǒng)在使用傳統(tǒng)I/O上已經(jīng)工作得很好且沒有更多的性能等方面的要求,千萬不要盲目地使用nio來重構(gòu)(也許在你的系統(tǒng)的上下文環(huán)境中,使用nio所帶來其它方面的復(fù)雜性會提高,處理增多,整體效率并未提高),這至少不符合敏捷開發(fā)的態(tài)度,簡單說,不要為了nio而nio。當然這不阻礙我們對nio的認識。

       Java nio是在Java編程中對I/O的另外一種高級的抽象方式。其對I/O的使用方式也更加貼近操作系統(tǒng)使用I/O的方式:通道和字節(jié)緩沖。一般的用法可以參考<<Thinking in java>>。這里我們談?wù)勈褂胣io進行網(wǎng)絡(luò)通信編程的特點。基本的Java socket編程對小規(guī)模的系統(tǒng)可以很好的工作,但是在資源不擴展而用戶請求不斷增大的情況下,系統(tǒng)劣化的比率很大。我們通常會面臨這樣一些這些問題:

    1、thread-per-request 的方式,這樣會有更多線程維護和切換的系統(tǒng)開銷,同時在系統(tǒng)擴展性方面受到限制。

    2、針對問題1,我們可以采用線程池的方式來節(jié)省線程創(chuàng)建、維護以及切換的開銷,但是這樣也會限制系統(tǒng)可以同時處理客戶端的數(shù)量,至少對一些長連接協(xié)議來說是這樣。此時增加線程池的大小是不能再提高系統(tǒng)性能的,而只會增加系統(tǒng)更多的線程開銷。

    3、傳統(tǒng)的socket在讀/寫數(shù)據(jù)以及建立連接上都是阻塞式的(沒有數(shù)據(jù)可讀可能會阻塞;沒有足夠空間緩存?zhèn)鬏數(shù)臄?shù)據(jù)可能阻塞;服務(wù)端的accept方法以及socket構(gòu)造函數(shù)都會阻塞等待,直到連接建立) 。這些特性會降低整個系統(tǒng)對CPU的利用率以及系統(tǒng)的活躍性,降低系統(tǒng)對客戶請求的響應(yīng)性及響應(yīng)時間,在某些情況下是不可接受的甚至會帶來災(zāi)難性的結(jié)果。在這樣的情形下,我們要解決cpu利用率、線程活躍性以及提高系統(tǒng)吞吐量,我們勢必做很多額外的工作且相當復(fù)雜。

    4、由于傳統(tǒng)socket的阻塞特性,每個對等端都在阻塞等待另外一端完成相關(guān)處理,這樣勢必增大死鎖的風險。

    5、當然為了提高系統(tǒng)的活躍性,傳統(tǒng)的socket在accept、構(gòu)造socket以及read方法上都增加了超時控制的處理以及使用socket.close方法來打斷一些阻塞操作,而網(wǎng)絡(luò)總是不確定的,設(shè)置這些超時時間的設(shè)置在具體的上下文環(huán)境中的取值也是比較復(fù)雜的。簡而言之,為了提高系統(tǒng)的活躍性會增大系統(tǒng)的復(fù)雜度。

         那么,Java nio真的就是Java socket編程解決以上若干問題的靈丹妙藥嗎?答案是否定的。

         nio的非阻塞特性是nio最大的特點,所謂非阻塞無非就是將通信的信道設(shè)置成為非阻塞的情況下,對該信道的所有操作都是會立即返回的。如數(shù)據(jù)讀取,沒有數(shù)據(jù)的時候會返回0而不是阻塞在信道上。這樣就增大了系統(tǒng)的活躍性,使得系統(tǒng)不必浪費資源的I/O操作上,系統(tǒng)可以更好的利用cpu資源做一些其它處理,在某些場景下會提高系統(tǒng)的響應(yīng)性以及吞吐量。

         同時nio在網(wǎng)絡(luò)通信的中采用的網(wǎng)絡(luò)I/O事件驅(qū)動的方式,即操作系統(tǒng)對用戶感興趣的通信信道及其上面的I/O事件進行監(jiān)聽并通知應(yīng)用程序。這實際上也是觀察者模式的一種應(yīng)用,在這樣的背景下,問題4中的死鎖風險幾乎就沒有了。

         如果你開發(fā)的服務(wù)端不是迭代服務(wù)器(順序化處理每個客戶請求),那么對于問題1、2在nio服務(wù)器中也是一樣的。換句話說,我們開發(fā)的并發(fā)處理服務(wù)器為了實現(xiàn)對各種網(wǎng)絡(luò)I/O事件的處理,并對每種我們所關(guān)心的網(wǎng)絡(luò)I/O事件進行及時響應(yīng),采用thread-per-request或者線程池的方式是無法避免的。所以很多人會感覺nio的網(wǎng)絡(luò)編程結(jié)構(gòu)與非nio的網(wǎng)絡(luò)編程結(jié)構(gòu)實際是一樣的,accept換成了select,監(jiān)聽連接入站編程了監(jiān)聽信道上感興趣的I/O事件,為了提高系統(tǒng)的處理能力,還是要啟動異步的線程來處理信道上的網(wǎng)絡(luò)I/O事件,只是具體實現(xiàn)不一樣而已。這說明nio并沒有改變我們服務(wù)端程序編寫的整體結(jié)構(gòu),只是在nio的環(huán)境下,我們的確可以去提高系統(tǒng)的活躍性、響應(yīng)性和吞吐量。nio與非nio在讀/寫網(wǎng)絡(luò)數(shù)據(jù)以及連接建立等網(wǎng)絡(luò)操作上是沒有多大區(qū)別的,這些因素主要都還是取決于網(wǎng)絡(luò)狀況、操作系統(tǒng)協(xié)議棧實現(xiàn)、應(yīng)用自身處理網(wǎng)絡(luò)數(shù)據(jù)的方式等多個方面。甚至,我們在享用nio的同時在一定程度上還會增大了網(wǎng)絡(luò)編程的復(fù)雜度,因為數(shù)據(jù)的讀寫以及連接的建立等操作變得更加不確定,當然最終網(wǎng)絡(luò)編程的復(fù)雜還是取決于協(xié)議的復(fù)雜度。

    posted @ 2010-10-01 14:31 jclown 閱讀(2568) | 評論 (2)編輯 收藏

    2010年9月19日 #

         摘要: Apache MINA 以及網(wǎng)絡(luò)NIO編程剖析。旨在用MINA的實現(xiàn)來詮釋JAVA NIO 網(wǎng)路編程的深意。  閱讀全文
    posted @ 2010-09-19 21:59 jclown 閱讀(2532) | 評論 (2)編輯 收藏

          ThreadLocal是線程變量的意思,不是本地線程。它可以為線程分配特有的空間(與線程自身的堆棧不同,是線程對象在內(nèi)存中的一個Map),使得線程可以通過這個空間隨時獲取自己相關(guān)的上下文信息。

    ThreadLocal 內(nèi)幕

    ThreadLocal很容易讓使用者誤解(以前我就誤解了),因為在這個類中定義了一個靜態(tài)的包級可見的內(nèi)部類ThreadLocalMap,同時ThreadLocal對外提供了get和set方法。那么set的時候就是把當前線程對象作為ThreadLocalMap的key,把傳入set方法的值作為value存儲起來;get的時候通過獲取當前線程對象,然后到ThreadLocalMap中取得對應(yīng)的value。這種認識是表面的很容易理解的方式,但是也是錯誤的理解。

    每個Thread類中都有ThreadLocal.ThreadLocalMap的兩個成員,分別是threadlocals與inheritableThreadLocals。前者用來存儲當前線程的相關(guān)數(shù)據(jù)信息,后者用來存儲從父線程中繼承或者說拷貝過來的相關(guān)數(shù)據(jù)信息。這兩個區(qū)域也就是前面提到的線程的特別存儲區(qū)域,但是如何操作它們?JDK中的設(shè)計并不是讓用戶直接操作當前線程來存取數(shù)據(jù),而是讓用戶操作ThreadLocal來對當前線程的這兩個Map進行存取(個人認為這樣設(shè)計是出于安全性與易用性考慮,主要是Map中的key值需要固定才能取到同一對象),同時放置在這兩個Map中的key值就是ThreadLocal對象自身,value由用戶傳入。


    ThreadLocal 進階

    ThreadLocal為線程獨占某些對象或者資源提供了新的手段,ThreadLocal與線程堆棧都是用來存取線程私有數(shù)據(jù)的區(qū)域,別的線程無法觸碰這兩個區(qū)域,但是二者確有不同的生命周期。這個可以這樣理解,線程跨多個方法調(diào)用的時候,方法作為Frame不斷的進棧和出棧(方法的調(diào)用與返回),同時出棧的時候方法中的臨時變量數(shù)據(jù)會被回收,在這個線程的堆棧中消失,所以方法中的局部變量是無法在線程調(diào)用過程中穿透,除非是傳遞局部的引用類型變量,但是這也意味著方法接口都要額外接收新的參數(shù)(早期系統(tǒng)中傳遞JDBC數(shù)據(jù)庫連接的方式)。而ThreadLocal不同,準確地說是線程中的ThreadLocalMap不同,線程對象中的ThreadLocalMap對象是伴隨整個線程對象生命周期的,線程可以在任何需要的時候通過它來獲取相關(guān)數(shù)據(jù),這為線程獨占數(shù)據(jù)提供了一種更加優(yōu)雅的方式。只不過這一切都是通過ThreadLocal來操作的而已,同時ThreadLocal自身也作為不同線程中的ThreadLocalMap中的key來映射存入的value。

    ThreadLocal 應(yīng)用

    public class ThreadWriter

    {

       private static final ThreadLocal<FileWriter> local = new

    ThreadLocal<FileWriter>();

        public void write(String s)

        {

           try

           {

               getFileWriter().write(s);

           }

           catch(IOException e)

           {

               //igore

           }

        }

        private FileWriter getFileWriter()

        {

           FileWriter fw = local.get();

           if (null == fw)

           {

               try

               {

    fw = new FileWriter(Thread.currentThread().getName() + "-info.txt", true);

                  local.set(fw);

               }

               catch(IOException e)

               {

                 //igore

               }

           }

           return fw;

        }

    }

    這里說明幾個問題:

    1、 ThreadLocal對象只有一份,它將作為不同線程中的ThreadLocalMap對象的key,所映射的值是不同文件路徑的FileWriter對象。只不過不同 線程中的ThreadLocalMap中的key值都一樣,但是因為在不同的ThreadLocalMap中,不會有任何影響,反而這樣的方式為每個線程中ThreadLocalMap對象中的key值生成省去了很多功夫,這是一個很精妙的設(shè)計,用戶在間接使用ThreadLocalMap的時候,不需要感知key是什么,就可以方便地存取。

    2、 一份ThreadLocal對象只能映射一種資源。如需要映射多種資源的話,定義多個ThreadLocal成員。

    3、 local.set(fw); 這句代碼表示將local自身作為key,fw作為value,存儲在調(diào)用這行代碼的線程中的ThreadLocalMap對象中。

    FileWriter fw = local.get(); 這句代碼表示將local自身作為key,從當前線程的ThreadLocalMap對象中取出屬于自己獨占的FileWriter對象。 

    posted @ 2010-09-19 20:06 jclown 閱讀(2224) | 評論 (2)編輯 收藏

    主站蜘蛛池模板: 182tv免费视视频线路一二三| 色费女人18女人毛片免费视频| 久久精品无码专区免费| 免费a级毛片无码av| 男人的天堂av亚洲一区2区| 男男AV纯肉无码免费播放无码 | 免费一级毛片在线播放| 亚洲欧洲免费无码| 在线A级毛片无码免费真人| 亚洲人成网国产最新在线| 性感美女视频免费网站午夜| 久久亚洲精品国产精品婷婷| 在线免费视频一区二区| 亚洲国产乱码最新视频| 最新69国产成人精品免费视频动漫| 亚洲狠狠成人综合网| 国产免费牲交视频| 羞羞视频在线观看免费| 亚洲深深色噜噜狠狠爱网站| 久久青草免费91线频观看不卡| 久久亚洲AV无码精品色午夜| 亚洲精品在线免费看| 亚洲一区二区三区写真| 国产成人免费全部网站 | 国产在线观a免费观看| 亚洲AV综合色区无码一区| 免费看又黄又无码的网站| 亚洲日本国产精华液| 成人黄动漫画免费网站视频 | 亚洲午夜久久影院| 欧美三级在线电影免费| 国产精品亚洲а∨天堂2021| 中文亚洲成a人片在线观看| 亚洲综合免费视频| 欧洲乱码伦视频免费国产| 亚洲va中文字幕无码久久不卡| 真人做A免费观看| 免费VA在线观看无码| 久久久久亚洲精品无码蜜桃| 国产在线国偷精品产拍免费| xvideos永久免费入口|