<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
    主站蜘蛛池模板: 99热在线精品免费全部my| 亚洲精品国偷自产在线| 五月婷婷在线免费观看| av电影在线免费看| 亚洲色成人网站WWW永久四虎| 亚洲国产另类久久久精品小说| 国产成人精品高清免费| 男人的好看免费观看在线视频 | 性做久久久久久久免费看| 免费在线观影网站| 午夜成人无码福利免费视频| 亚洲一区在线观看视频| 亚洲av无码国产精品色午夜字幕| 亚洲精品tv久久久久| 国产最新凸凹视频免费| 蜜桃精品免费久久久久影院| 丁香花免费完整高清观看| 在线视频精品免费| 免费人成在线观看网站品爱网| a级成人毛片免费图片| 亚洲免费在线观看| 国产JIZZ中国JIZZ免费看| 一级一级毛片免费播放| 男人j进女人p免费视频| 免费中文字幕视频| 黄色免费网站在线看| 国产91成人精品亚洲精品| 国产亚洲精品AAAA片APP| 亚洲av无码专区在线观看亚| 亚洲大尺度无码无码专线一区| 亚洲kkk4444在线观看| 亚洲色大网站WWW永久网站| 亚洲娇小性xxxx色| 亚洲午夜精品久久久久久app| 久久亚洲最大成人网4438 | 扒开双腿猛进入爽爽免费视频| 69成人免费视频| 毛片免费vip会员在线看| 岛国片在线免费观看| 日日操夜夜操免费视频| 成人亚洲综合天堂|