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

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

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

    linugb118--java space

    Java

    Java NIO---buffer部分

    Java NIO---buffer部分

    最近想建一個(gè)網(wǎng)絡(luò)傳輸?shù)钠脚_(tái),查看到了Jboss 的Netty,而他們核心的傳輸是用了JDK 1.4以后的
    NIO特性,因此借機(jī)會(huì)學(xué)習(xí)一下NIO
    NIO主要有下面幾大部分

    Buffer:Io的操作少不了緩存,通過(guò)Buffer能大大提高傳輸?shù)男剩瑯覰IO中也有Buffer的這部分
    Buffer針對(duì)數(shù)據(jù)類型有相應(yīng)的子類,他們都是繼承Buffer class
    比如CharBuffer,IntBuffer等等
    需要說(shuō)明的子類MappedByteBuffer 通過(guò)命名可以看出這個(gè)MappedByteBuffer有mapped+byte+Buffer組成
    據(jù)我理解 這么mapped 是指memory-mapped
    這里解釋一下memory-mapped, 以為我們說(shuō)的buffer 可能就是指物理上的內(nèi)存,包括jdk 以前的io
    一般情況下,buffer指物理上的內(nèi)存沒什么問(wèn)題,可以物理內(nèi)存畢竟比較有限,當(dāng)需要很大buffer存放數(shù)據(jù)的時(shí)候
    物理內(nèi)存就不夠,那么就引出一個(gè)虛擬內(nèi)存的概念,就像現(xiàn)在的os 一樣,也有虛擬內(nèi)存的概念,虛擬內(nèi)存本質(zhì)上
    是存在硬盤上的,只是物理內(nèi)存存放的不是具體的數(shù)據(jù)而是虛擬內(nèi)存上的地址,而具體的數(shù)據(jù)則是在虛擬內(nèi)存上,這樣
    物理內(nèi)存只是存放很多地址,這樣就大大增加了buffer的size。當(dāng)然如果你buffer的數(shù)據(jù)很小,也可以知道放入物理內(nèi)存
    因此我認(rèn)為 這個(gè)memory-mapped 是指的用虛擬內(nèi)存的哪種緩存模式

    A.Buffer的 attribute
    1.Capacity:buffer的大小,一個(gè)buffer按照某個(gè)Capacity創(chuàng)建后就不能修改
    2.Limit:用了多少buffer
    3.Position:指針,獲取下一個(gè)元素的位置,操作get(),put(),這個(gè)position會(huì)自動(dòng)更新(和iterator相似)
    4.Mark:被標(biāo)記的指針位置 通過(guò)mark()操作可以使mark = position 通過(guò)reset() 可以使position = mark

    上面這幾個(gè)屬性應(yīng)該符合下面條件
    0 <= mark <= position <= limit <= capacity


    B. fill:插入數(shù)據(jù)
    用put() 方法可以插入一段數(shù)據(jù) 但是這個(gè)時(shí)候postion 在插入這段數(shù)據(jù)的尾部

    C. flip:彈出數(shù)據(jù)
    因?yàn)樯厦鎸懭霐?shù)據(jù)后,指針在尾部不是從0開始,那么我們需要
    buffer.limit(buffer.position( )).position(0);
    將limit 設(shè)置為當(dāng)前的postion,limit 可以告訴方法這段數(shù)據(jù)什么時(shí)候結(jié)束,而具體可以調(diào)用方法
    hasRemaining( ) 來(lái)判斷是否數(shù)據(jù)結(jié)束。

    同時(shí)將當(dāng)前指針設(shè)置為0
    NIO 提供了方法buffer.flip()完成上面的動(dòng)作

    另外方法rewind( )和flip相似 只是區(qū)別在于flip要修改limit,而rewind不修改limit
    rewind 用處可以在已經(jīng)flip后,還能重讀這段數(shù)據(jù)

    Buffer不是線程安全的,如果你想要多線程同時(shí)訪問(wèn),那么需要用synchronization

    D. Mark:讓buffer記住某個(gè)指針,已備后面之用。
    調(diào)用mark()就能將當(dāng)前指針mark住
    而調(diào)用reset()就能將當(dāng)前指針回到mark了的指針位置,如果mark未定義,那么調(diào)用reset就會(huì)報(bào)InvalidMarkException
    此外rewind( ), clear( ), and flip( )這些操作將會(huì)拋棄mark,這樣clear()和reset()區(qū)別
    clear表示清空buffer 而reset表示能將當(dāng)前指針回到mark了的指針位置

    E:Comparing:buffer 也是java的object sub class,所有buffer也能對(duì)象進(jìn)行比較
    public abstract class ByteBuffer
    extends Buffer implements Comparable
    {
    // This is a partial API listing
    public boolean equals (Object ob)
    public int compareTo (Object ob)
    }

    兩個(gè)buffer 認(rèn)為相等,需要具備下面條件
    1.buffer 類型相同
    2.buffer里面保留的元素?cái)?shù)量相同,buffer capacities不需要相同,這里需要注意保留的元素是指有效的元素,不是指buffer里面有的元素。
    其實(shí)就從position到limit這段的元素,當(dāng)然當(dāng)前的postion和limit值都可以不相同,但這段數(shù)據(jù)要相同
    3.remaining data 的數(shù)據(jù)順序要相同,可以通過(guò)get()來(lái)循環(huán)獲取出來(lái)后判斷每個(gè)element都相同

    如果同時(shí)符合上面三個(gè)條件,那么就表示buffer object 相等

    F:Bulk Moves
    如何在buffer中大塊的數(shù)據(jù)移動(dòng),對(duì)性能起到關(guān)鍵作用
    他的做法是get的時(shí)候,將一塊數(shù)據(jù)取出放入數(shù)組里面,這樣比起循環(huán)get()一個(gè)byte要效率高多了,那么對(duì)于塊狀數(shù)據(jù)總是有個(gè)指定的長(zhǎng)度
    這個(gè)長(zhǎng)度就是指定數(shù)組的長(zhǎng)度
    public CharBuffer get (char [] dst, int offset, int length)
    這里就是length。
    如果只有參數(shù)為數(shù)組buffer.get (myArray);
    那么其實(shí)也是指定了長(zhǎng)度,只是長(zhǎng)度為數(shù)組的長(zhǎng)度,上面的語(yǔ)句等同于
    buffer.get (myArray, 0, myArray.length);
    針對(duì)上面,有可能buffer的data 小于myArray.length,這個(gè)時(shí)候如果取buffer 那么會(huì)報(bào)錯(cuò)
    所以需要下面的寫法
     char [] bigArray = new char [1000];
     // Get count of chars remaining in the buffer
     int length = buffer.remaining( );
     // Buffer is known to contain < 1,000 chars
     buffer.get (bigArrray, 0, length);
     // Do something useful with the data
     processData (bigArray, length);
     這是buffer<length
     如果buffer>length 那需要loop:
     char [] smallArray = new char [10];
     while (buffer.hasRemaining( )) {
     int length = Math.min (buffer.remaining( ), smallArray.length);
     buffer.get (smallArray, 0, length);
     processData (smallArray, length);
     }

    同樣操作put是將array中的數(shù)據(jù)放入buffer,他同樣有上面length的問(wèn)題,需要用remaining來(lái)判斷

    G:創(chuàng)建Buffer: buffer class 不能直接new創(chuàng)建,他們都是abstract class,但是他們都有static factory,通過(guò)factory可以創(chuàng)建instances
    比如
    public abstract class CharBuffer
    extends Buffer implements CharSequence, Comparable
    {
    // This is a partial API listing
    public static CharBuffer allocate (int capacity)
    public static CharBuffer wrap (char [] array)
    public static CharBuffer wrap (char [] array, int offset,
    int length)
    public final boolean hasArray( )
    public final char [] array( )
    public final int arrayOffset( )
    }

    可以通過(guò)allocation或者wrapping來(lái)創(chuàng)建buffer
    Alloction:允許分配私有buffer
    CharBuffer charBuffer = CharBuffer.allocate (100);
    wrapping:不允許分配私有buffer,顯性提供存儲(chǔ)
    char [] myArray = new char [100];
    CharBuffer charbuffer = CharBuffer.wrap (myArray);

    而myArray  叫做buffer的backing array
    通過(guò)hasArray( ) 判斷buffer是否存在backing array
    如果為true,可通過(guò)array()得到array的引用

    H:Duplicating Buffers  復(fù)制buffer
    Duplicat() 創(chuàng)建一個(gè)和原來(lái)一樣的新的buffer,他們都有各自的postion,limit,mark, 但是共享同樣的數(shù)據(jù),也就是說(shuō)任何一個(gè)buffer被修改了
    他們看到的數(shù)據(jù)也就修改了。創(chuàng)建的新buffer繼承了老buffer的屬性,比如如果老buffer為readonly,那么新的也是readonly
    asReadOnlyBuffer( ) 和Duplicat()相似,只是區(qū)別asReadOnlyBuffer( ) 創(chuàng)建的buffer總是readonly
    slice() 和Duplicat()也相似,不同之處在于slice() 將修改buffer的capacity=(limit - position),同時(shí)新buffer以老buffer的當(dāng)前postion作為開始
    指針。

    I:Byte Buffers 可以獲取不同類型的buffer,另外byte本身也能排序

    J:Direct Buffers: 對(duì)于操作系統(tǒng)來(lái)說(shuō),內(nèi)存存儲(chǔ)的數(shù)據(jù)不一定是連續(xù)的。而Direct buffer直接用于和io設(shè)備進(jìn)行交互,對(duì)于io設(shè)備操作的buffer只能是
    direct buffer,如果是nondirect ByteBuffer需要寫入設(shè)備,那么他首先是創(chuàng)建一個(gè)臨時(shí)的direct byteBuffer,然后將內(nèi)容考入這個(gè)臨時(shí)direct buffer,
    接著進(jìn)行底層的io操作,完成io操作后,臨時(shí)buffer將被垃圾回收。
    ByteBuffer.allocateDirect()創(chuàng)建direct buffer,isDirect( )則判斷buffer是否是direct buffer

    K:View Buffers  當(dāng)一堆數(shù)據(jù)被收到后需要先查看他,然后才能確定是send還是怎么處理,這個(gè)時(shí)候就要引入View buffer
    View Buffer擁有自己的屬性,比如postion,limit,mark,但是他是和初始buffer共享數(shù)據(jù)的,這個(gè)和duplicated,sliced相似,但是view Buffer
    能將raw bytes 映射為指定的基礎(chǔ)類型buffer,這個(gè)也是查看的具體內(nèi)容了,我們也可以認(rèn)為是byte buffer向其他基礎(chǔ)類型buffer的轉(zhuǎn)換

    public abstract class ByteBuffer
    extends Buffer implements Comparable
    {
    // This is a partial API listing
    public abstract CharBuffer asCharBuffer( );
    public abstract ShortBuffer asShortBuffer( );
    public abstract IntBuffer asIntBuffer( );
    public abstract LongBuffer asLongBuffer( );
    public abstract FloatBuffer asFloatBuffer( );
    public abstract DoubleBuffer asDoubleBuffer( );
    }

     

     

     

     

     

     

     

     

     

     

    posted on 2010-09-01 16:01 linugb118 閱讀(1721) 評(píng)論(0)  編輯  收藏


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     

    My Links

    Blog Stats

    常用鏈接

    留言簿(1)

    隨筆檔案

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 蜜桃视频在线观看免费网址入口| 久久狠狠躁免费观看2020| 色se01短视频永久免费| 亚洲AV永久无码精品| 永久免费av无码入口国语片| 亚洲精品无码久久一线| 亚洲免费一区二区| 狠狠色婷婷狠狠狠亚洲综合| GOGOGO高清免费看韩国| 国产亚洲无线码一区二区| 二个人看的www免费视频| 亚洲爆乳无码专区| 美女内射毛片在线看免费人动物| 亚洲欧洲视频在线观看| 亚洲中文无码永久免费 | 亚洲综合伊人久久综合| 两个人看的www高清免费观看| 亚洲精品国产精品乱码视色| 色欲A∨无码蜜臀AV免费播 | 亚洲一区二区三区自拍公司| 丝瓜app免费下载网址进入ios| 亚洲AV永久无码区成人网站 | 国产成人无码综合亚洲日韩| 91精品国产免费久久国语蜜臀 | 亚洲色偷偷偷综合网| 免费a级毛片18以上观看精品| 国产精品美女免费视频观看| 亚洲国产综合91精品麻豆| 亚洲免费人成视频观看| 久久亚洲中文无码咪咪爱| 亚洲日韩精品一区二区三区 | 久久久久亚洲AV无码专区体验 | 亚洲精品无码久久毛片| 黄页免费在线观看| 久久亚洲精品国产亚洲老地址| 国产片免费福利片永久| 91香蕉国产线在线观看免费| 亚洲国产精品无码久久久秋霞1| 中文字幕久久亚洲一区| 久久久高清免费视频| 一区二区三区在线观看免费|