java中共享內存的實現

JDK1.4裏面的MappedByteBuffer爲開發人員在java中實現共享內存提供了良好的方法,該
緩衝區實際上是一個磁盤文件的內存映像,二者的變化會保持同步,即內存數據發生變化過後會立即反
應到磁盤文件中,這樣會有效的保證共享內存的實現,將共享文件和磁盤文件建立聯繫的是文件通道類
:FileChannel,該類的加入是JDK爲了統一外圍設備的訪問方法,並且加強了多線程對同一個文件進
行存取的安全性,這裏可以使用它來建立共享內存用,它建立了共享內存和磁盤文件之間的一個通道。
打開一個文件可使用RandomAccessFile類的getChannel方法,該方法直接放回一個文件通道,該文
件通道由於對應的文件設爲隨機存取,一方面可以進行讀寫兩種操作,另一方面使用它不會破壞共享文
件的內。這裏,如果使用FileOutputStream和FileOutputStream則不能理想的實現共享內存的要求
,因爲這兩個類同時實現自由讀寫很困難。
下邊的代碼實現了上邊提及的共享內存功能
//獲得一個只讀的隨機存取文件對象
RandomAccessFile RAFile = new RandomAccessFile(filename,"r");
//獲得相應的文件通道
FileChannel fc = RAFile.getChannel();
//取得文件的實際大小
int size = (int)fc.size();
//獲得共享內存緩衝區,該共享內存只讀
MappedByteBuffer mapBuf = fc.map(FileChannel.MAP_RO,0,size);
//獲得一個可讀寫的隨機存取文件對象
RAFile = new RandomAccessFile(filename,"rw");
//獲得相應的文件通道
fc = RAFile.getChannel();
//獲得文件的實際大小,以便映像到共享內存
size = (int)fc.size();
//獲得共享內存緩衝區,該共享內存可讀寫
mapBuf = fc.map(FileChannel.MAP_RW,0,size);
//獲取頭部消息:存取權限
int mode = mapBuf.getInt();


如果多個應用映像使用同一文件名的共享內存,則意味着這多個應用共享了同一內存數據,
這些應用對於文件可以具有同等存取權限,一個應用對數據的刷新會更新到多個應用中。爲了防止多個
應用同時對共享內存進行讀寫操作,可以在該共享內存的頭部信息加入寫操作標記,該共享內存的頭部
信息至少有:共享內存的長度,共享內存目前的存取模式。
共享內存的頭部信息是私有信息,多個應用可以對同一個共享內存執行寫操作,執行寫操作
和結束寫操作的時候,可以使用如下方法:
public boolean startWrite(){
if(mode == 0){     //存儲模式是0,表示可寫
mode = 1;  //意味着別的應用不可寫
mapBuf.flip();
mapBuf.putInt(mode);  //寫入共享內存的頭部信息
return true;
}
else{
//表明已經有應用在寫該共享內存了,本應用不能夠針對共享內存再做
寫操作
return false; 
}
}


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


上邊提供了對共享內存執行寫操作過程的兩個方法,這兩個方法其實理解起來很容易,真正
需要思考的事一個針對存取模式的設置,其實這種機制和內存的鎖模式有點類似,一旦當mode設置爲
可寫的時候,startWrite才能返回true,不僅僅如此,某個應用程序在向共享內存寫入數據的時候還
是會修改其存取模式,因爲如果不修改的話就會導致其他應用同樣針對該內存是可寫的,這樣就導致共
享內存的實現變得混亂,而在停止寫操作stopWrite的時候,需要將mode設置爲0,也就是上邊註釋段
提到的釋放寫權限。
java中共享內存的應用:
1.永久對象的配置
2.共享數據的查詢



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章