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

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

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

    gembin

    OSGi, Eclipse Equinox, ECF, Virgo, Gemini, Apache Felix, Karaf, Aires, Camel, Eclipse RCP

    HBase, Hadoop, ZooKeeper, Cassandra

    Flex4, AS3, Swiz framework, GraniteDS, BlazeDS etc.

    There is nothing that software can't fix. Unfortunately, there is also nothing that software can't completely fuck up. That gap is called talent.

    About Me

     

    Java 共享內(nèi)存

    共享內(nèi)存可以說是最有用的進(jìn)程間通信方式,也是最快的IPC(Inter-Process Communication)形式。兩個(gè)不同進(jìn)程A、B共享內(nèi)存的意思是,同一塊物理內(nèi)存被映射到進(jìn)程A、B各自的進(jìn)程地址 空間。進(jìn)程A可以即時(shí)看到進(jìn)程B對(duì)共享內(nèi)存中數(shù)據(jù)的更新,反之亦然。由于多個(gè)進(jìn)程共享同一塊內(nèi)存區(qū)域,必然需要某種同步機(jī)制,互斥鎖和信號(hào)量都可以。

    采用共享內(nèi)存通信的一個(gè)顯而易見的好處是效率高,因?yàn)檫M(jìn)程可以直接讀寫內(nèi)存,而不需要任何數(shù)據(jù)的拷貝。對(duì)于像管道和消息隊(duì)列等通信方式,則需要在內(nèi)核和用 戶空間進(jìn)行四次的數(shù)據(jù)拷貝,而共享內(nèi)存則只拷貝兩次數(shù)據(jù):一次從輸入文件到共享內(nèi)存區(qū),另一次從共享內(nèi)存區(qū)到輸出文件。實(shí)際上,進(jìn)程之間在共享內(nèi)存時(shí),并 不總是讀寫少量數(shù)據(jù)后就解除映射,有新的通信時(shí),再重新建立共享內(nèi)存區(qū)域。而是保持共享區(qū)域,直到通信完畢為止,這樣,數(shù)據(jù)內(nèi)容一直保存在共享內(nèi)存中,并 沒有寫回文件。共享內(nèi)存中的內(nèi)容往往是在解除映射時(shí)才寫回文件的。因此,采用共享內(nèi)存的通信方式效率是非常高的。

    共享內(nèi)存的使用有如下幾個(gè)特點(diǎn):

    1. 可以被多個(gè)進(jìn)程打開訪問;
    2. 讀寫操作的進(jìn)程在執(zhí)行讀寫操作時(shí)其他進(jìn)程不能進(jìn)行寫操作;
    3. 多個(gè)進(jìn)程可以交替對(duì)某一共享內(nèi)存執(zhí)行寫操作;
    4. 一個(gè)進(jìn)程執(zhí)行了內(nèi)存的寫操作后,不影響其他進(jìn)程對(duì)該內(nèi)存的訪問。同時(shí)其他進(jìn)程對(duì)更新后的內(nèi)存具有可見性。
    5. 在進(jìn)程執(zhí)行寫操作時(shí)如果異常退出,對(duì)其他進(jìn)程寫操作禁止應(yīng)自動(dòng)解除。
    6. 相對(duì)共享文件,數(shù)據(jù)訪問的更方便更效率

    另外,共享內(nèi)存的使用上有如下情況:

    獨(dú)占的寫操作,相應(yīng)有獨(dú)占的寫操作等待隊(duì)列。獨(dú)占的寫操作本身不會(huì)發(fā)生數(shù)據(jù)的一致性問題。
    共享的寫操作,相應(yīng)有共享的寫操作等待隊(duì)列。共享的寫操作則要注意防止發(fā)生數(shù)據(jù)的一致性問題。
    獨(dú)占的讀操作,相應(yīng)有共享的讀操作等待隊(duì)列;
    共享的讀操作,相應(yīng)有共享的讀操作等待隊(duì)列。

    共享內(nèi)存在java中的實(shí)現(xiàn)
    在jdk1.4中提供的類MappedByteBuffer為我們實(shí)現(xiàn)共享內(nèi)存提供了較好的方法。該緩 沖區(qū)實(shí)際上是一個(gè)磁盤文件的內(nèi)存映像。二者的變化將保持同步,即內(nèi)存數(shù)據(jù)發(fā)生變化會(huì)立 刻反映到磁盤文件中,這樣會(huì)有效的保證共享內(nèi)存的實(shí)現(xiàn)。

    將 共享內(nèi)存和磁盤文件建立聯(lián)系的是文件通道類:FileChannel。該類的加入是JDK為 了統(tǒng)一對(duì)外部設(shè)備(文件、網(wǎng)絡(luò)接口等)的訪問方法,并且加強(qiáng)了多線程對(duì)同一文件進(jìn)行存 取的安全性。例如讀寫操作統(tǒng)一成read和write。這里只是用它來建立共享內(nèi)存用,它建立 了共享內(nèi)存和磁盤文件之間的一個(gè)通道。

    打 開一個(gè)文件建立一個(gè)文件通道可以用RandomAccessFile類中的方法getChannel。該 方法將直接返回一個(gè)文件通道。該文件通道由于對(duì)應(yīng)的文件設(shè)為隨機(jī)存取文件,一方面可以 進(jìn)行讀寫兩種操作,另一方面使用它不會(huì)破壞映像文件的內(nèi)容(如果用FileOutputStream直 接打開一個(gè)映像文件會(huì)將該文件的大小置為0,當(dāng)然數(shù)據(jù)會(huì)全部丟失)。這里,如果用 FileOutputStream和FileInputStream則不能理想的實(shí)現(xiàn)共享內(nèi)存的要求,因?yàn)檫@兩個(gè)類同時(shí) 實(shí)現(xiàn)自由的讀寫操作要困難得多。

    下面的代碼實(shí)現(xiàn)了如上功能,它的作用類似UNIX系統(tǒng)中的mmap函數(shù)。

    // 獲得一個(gè)只讀的隨機(jī)存取文件對(duì)象
    RandomAccessFile RAFile = new RandomAccessFile(filename,"r");

    // 獲得相應(yīng)的文件通道
    FileChannel fc = RAFile.getChannel();

    // 取得文件的實(shí)際大小,以便映像到共享內(nèi)存
    int size = (int)fc.size();

    // 獲得共享內(nèi)存緩沖區(qū),該共享內(nèi)存只讀
    MappedByteBuffer mapBuf = fc.map(FileChannel.MAP_RO,0,size);

    // 獲得一個(gè)可讀寫的隨機(jī)存取文件對(duì)象
    RAFile = new RandomAccessFile(filename,"rw");

    // 獲得相應(yīng)的文件通道
    fc = RAFile.getChannel();

    // 取得文件的實(shí)際大小,以便映像到共享內(nèi)存
    size = (int)fc.size();

    // 獲得共享內(nèi)存緩沖區(qū),該共享內(nèi)存可讀寫
    mapBuf = fc.map(FileChannel.MAP_RW,0,size);

    // 獲取頭部消息:存取權(quán)限
    mode = mapBuf.getInt();

    如果多個(gè)應(yīng)用映像同一文件名的共享內(nèi)存,則意味著這多個(gè)應(yīng)用共享了同一內(nèi)存數(shù)據(jù)。 這些應(yīng)用對(duì)于文件可以具有同等存取權(quán)限,一個(gè)應(yīng)用對(duì)數(shù)據(jù)的刷新會(huì)更新到多個(gè)應(yīng)用中。

    為了防止多個(gè)應(yīng)用同時(shí)對(duì)共享內(nèi)存進(jìn)行寫操作,可以在該共享內(nèi)存的頭部信息加入寫操 作標(biāo)志。該共享內(nèi)存的頭部基本信息至少有:
    int Length; // 共享內(nèi)存的長度。
    int mode; // 該共享內(nèi)存目前的存取模式。




    共享內(nèi)存的頭部信息是類的私有信息,在多個(gè)應(yīng)用可以對(duì)同一共享內(nèi)存執(zhí)行寫操作時(shí), 開始執(zhí)行寫操作和結(jié)束寫操作時(shí),需調(diào)用如下方法:
    public boolean StartWrite()
    {
    if(mode == 0) { // 標(biāo)志為0,則表示可寫
    mode = 1; // 置標(biāo)志為1,意味著別的應(yīng)用不可寫該共享內(nèi)存
    mapBuf.flip();
    mapBuf.putInt(mode); // 寫如共享內(nèi)存的頭部信息
    return true;
    }
    else {
    return false; // 指明已經(jīng)有應(yīng)用在寫該共享內(nèi)存,本應(yīng)用不可寫該共享內(nèi)存
    }
    }

    public boolean StopWrite()
    {
    mode = 0; // 釋放寫權(quán)限
    mapBuf.flip();
    mapBuf.putInt(mode); // 寫入共享內(nèi)存頭部信息
    return true;
    }

    這里提供的類文件mmap.java封裝了共享內(nèi)存的基本接口,讀者可以用該類擴(kuò)展成自己 需要的功能全面的類。

    如 果執(zhí)行寫操作的應(yīng)用異常中止,那么映像文件的共享內(nèi)存將不再能執(zhí)行寫操作。為了 在應(yīng)用異常中止后,寫操作禁止標(biāo)志自動(dòng)消除,必須讓運(yùn)行的應(yīng)用獲知退出的應(yīng)用。在多線 程應(yīng)用中,可以用同步方法獲得這樣的效果,但是在多進(jìn)程中,同步是不起作用的。方法可 以采用的多種技巧,這里只是描述一可能的實(shí)現(xiàn):采用文件鎖的方式。寫共享內(nèi)存應(yīng)用在獲 得對(duì)一個(gè)共享內(nèi)存寫權(quán)限的時(shí)候,除了判斷頭部信息的寫權(quán)限標(biāo)志外,還要判斷一個(gè)臨時(shí)的 鎖文件是否可以得到,如果可以得到,則即使頭部信息的寫權(quán)限標(biāo)志為1(上述),也可以 啟動(dòng)寫權(quán)限,其實(shí)這已經(jīng)表明寫權(quán)限獲得的應(yīng)用已經(jīng)異常退出,這段代碼如下:
    // 打開一個(gè)臨時(shí)的文件,注意同一共享內(nèi)存,該文件名要相同,可以在共享文件名后加后綴“.lock”。
    RandomAccessFile fis = new RandomAccessFile("shm.lock","rw");
    // 獲得文件通道
    FileChannel lockfc = fis.getChannel();
    // 獲得文件的獨(dú)占鎖,該方法不產(chǎn)生堵塞,立刻返回
    FileLock flock = lockfc.tryLock();
    // 如果為空,則表明已經(jīng)有應(yīng)用占有該鎖
    if(flock == null) {
    ...// 不能執(zhí)行寫操作
    }
    else {
    ...// 可以執(zhí)行寫操作
    }


    該鎖會(huì)在應(yīng)用異常退出后自動(dòng)釋放,這正是該處所需要的方法。

    3 共享內(nèi)存在java中的應(yīng)用
    共享內(nèi)存在java應(yīng)用中,經(jīng)常有如下兩種種應(yīng)用:

    永久對(duì)象配置。
    在 java服務(wù)器應(yīng)用中,用戶可能會(huì)在運(yùn)行過程中配置一些參數(shù),而這些參數(shù)需要永久 有效,當(dāng)服務(wù)器應(yīng)用重新啟動(dòng)后,這些配置參數(shù)仍然可以對(duì)應(yīng)用起作用。這就可以用到該文 中的共享內(nèi)存。該共享內(nèi)存中保存了服務(wù)器的運(yùn)行參數(shù)和一些對(duì)象運(yùn)行特性??梢栽趹?yīng)用啟 動(dòng)時(shí)讀入以啟用以前配置的參數(shù)。

    查詢共享數(shù)據(jù)。
    一個(gè)應(yīng)用是系統(tǒng)的服務(wù)進(jìn)程,其系統(tǒng)的運(yùn)行狀態(tài)記錄在共享內(nèi)存中,其中運(yùn)行狀態(tài)可能是不斷變化的。為了隨時(shí)了解系統(tǒng)的運(yùn)行狀態(tài),啟動(dòng)另一個(gè)應(yīng)用,該應(yīng)用查詢?cè)摴蚕韮?nèi)存,匯報(bào)系統(tǒng)的運(yùn)行狀態(tài)。

    可見,共享內(nèi)存在java應(yīng)用中還是很有用的,只要組織好共享內(nèi)存的數(shù)據(jù)結(jié)構(gòu),共享內(nèi)存就可以在應(yīng)用開發(fā)中發(fā)揮很不錯(cuò)的作用。

    posted on 2008-04-11 11:22 gembin 閱讀(3840) 評(píng)論(1)  編輯  收藏 所屬分類: JavaSE

    評(píng)論

    # re: Java 共享內(nèi)存 2008-04-12 10:52 豆抓電影搜索

    共想?http://www.douzhua.com  回復(fù)  更多評(píng)論   

    導(dǎo)航

    統(tǒng)計(jì)

    常用鏈接

    留言簿(6)

    隨筆分類(440)

    隨筆檔案(378)

    文章檔案(6)

    新聞檔案(1)

    相冊(cè)

    收藏夾(9)

    Adobe

    Android

    AS3

    Blog-Links

    Build

    Design Pattern

    Eclipse

    Favorite Links

    Flickr

    Game Dev

    HBase

    Identity Management

    IT resources

    JEE

    Language

    OpenID

    OSGi

    SOA

    Version Control

    最新隨筆

    搜索

    積分與排名

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    free counters
    主站蜘蛛池模板: 免费的全黄一级录像带| 日本免费福利视频| 亚洲中文字幕一二三四区| 可以免费观看的一级毛片| 久久青青草原国产精品免费| 亚洲第一男人天堂| 国产亚洲av人片在线观看| 免费毛片a在线观看67194| 又长又大又粗又硬3p免费视频| 亚洲精品国产成人专区| 精品少妇人妻AV免费久久洗澡| 国产午夜精品久久久久免费视 | 亚洲色自偷自拍另类小说| 成年人免费的视频| 久久精品免费网站网| 亚洲国产成人99精品激情在线| 国产亚洲精aa成人网站| 四虎永久在线精品免费网址| 中文毛片无遮挡高清免费| 亚洲性色AV日韩在线观看| 亚洲AV无码日韩AV无码导航| 免费一级做a爰片久久毛片潮喷| 67pao强力打造高清免费| 一级午夜a毛片免费视频| 亚洲啪AV永久无码精品放毛片| 久久久综合亚洲色一区二区三区| 免费人成视频在线观看视频| 欧洲乱码伦视频免费| 久久狠狠躁免费观看| 四虎精品免费永久免费视频| 亚洲色大成网站www尤物| 91在线精品亚洲一区二区| 亚洲熟女少妇一区二区| 四虎1515hm免费国产| 最近中文字幕免费mv视频8| 99久久免费精品视频| 国产精品网站在线观看免费传媒 | 少妇中文字幕乱码亚洲影视| 久久久久亚洲AV综合波多野结衣 | 亚洲?V乱码久久精品蜜桃| 在线a级毛片免费视频|