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

 

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信