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.共享数据的查询



 

你可能感兴趣的:(java)