java进程通讯显存共享文件加锁java进程通讯显存共享文件加锁进程间的通信无非就是读写文件,socket通信或则使用共享显存。你不想用读写文件的方法进程共享内存读写锁,那就用共享显存或则socket通信的方法。我个人认为用socket比较简单,其实是由于我对socket比较熟悉。下边是一篇java实现共享显存的文章,java无法管理显存,当然他也是靠创建映像文件来实现的。共享显存在java中的实现在jdk1.4中提供的类MappedByteBuffer为我们实现共享显存提供了较好的技巧。该缓冲区实际上是一个c盘文件的显存映像。两者的变化将保持同步,即显存数据发生变化会立即反映到c盘文件中,这样会有效的保证共享显存的实现。将共享显存和c盘文件构建联系的是文件通道类:FileChannel。该类的加入是JDK为了统一对外部设备(文件、网络插口等)的访问方式,但是强化了多线程对同一文件进行存取的安全性。诸如读写操作统一成read和write。这儿只是用它来构建共享显存用,它构建了共享显存和c盘文件之间的一个通道。打开一个文件构建一个文件通道可以用RandomAccessFile类中的方式getChannel。
该方式将直接返回一个文件通道。该文件通道因为对应的文件设为随机存取文件,一方面可以进行读写两种操作,另一方面使用它不会破坏映像文件的内容(假如用FileOutputStream直接打开一个映像文件会将该文件的大小置为0,其实数据会全部遗失)。这儿,假如用FileOutputStream和FileInputStream则不能理想的实现共享显存的要求,由于这两个类同时实现自由的读写操作要困难得多。下边的代码实现了如上功能,它的作用类似UNIX系统中的mmap函数。//获得一个只读的随机存取文件对象RandomAccessFileRAFile=newRandomAccessFile(filename,"r");//获得相应的文件通道FileChannelfc=RAFile.getChannel();//取得文件的实际大小,便于映像到共享显存intsize=(int)fc.size();//获得共享显存缓冲区,该共享显存只读MappedByteBuffermapBuf=fc.map(FileChannel.MAP_RO,0,size);//获得一个可读写的随机存取文件对象RAFile=newRandomAccessFile(filename,"rw");//获得相应的文件通道fc=RAFile.getChannel();//取得文件的实际大小,便于映像到共享显存size=(int)fc.size();//获得共享显存缓冲区,该共享显存可读写mapBuf=fc.map(FileChannel.MAP_RW,0,size);//获取颈部消息:存取权限mode=mapBuf.getInt();假如多个应用映像同一文件名的共享显存,则意味着这多个应用共享了同一显存数据。
这种应用对于文件可以具有同等存取权限,一个应用对数据的刷新会更新到多个应用中。为了避免多个应用同时对共享显存进行写操作,可以在该共享显存的颈部信息加入写操作标志。该共享显存的颈部基本信息起码有:intLength;//共享显存的宽度。intmode;//该共享显存目前的存取模式。共享显存的颈部信息是类的私有信息,在多个应用可以对同一共享显存执行写操作时,开始执行写操作和结束写操作时,需调用如下方式:publicbooleanStartWrite(){if(mode==0){//标志为0,则表示可写mode=1;//置标志为1,意味着别的应用不可写该共享显存mapBuf.flip();mapBuf.putInt(mode);//写如共享显存的颈部信息returntrue;}else{returnfalse;//指明早已有应用在写该共享显存,本应用不可写该共享显存}}publicbooleanStopWrite(){mode=0;//释放写权限mapBuf.flip();mapBuf.putInt(mode);//写入共享显存颈部信息returntrue;}这儿提供的类文件mmap.java封装了共享显存的基本插口,读者可以用该类扩充成自己须要的功能全面的类。
假如执行写操作的应用异常终止,这么映像文件的共享显存将不再能执行写操作。为了在应用异常终止后,写操作严禁标志手动清除进程共享内存读写锁,必须让运行的应用得知退出的应用。在多线程应用中,可以用同步方式获得这样的疗效,并且在多进程中,同步是不起作用的。方式可以采用的多种方法,这儿只是描述一可能的实现:采用文件锁的形式。写共享显存应用在获得对一个共享显存写权限的时侯,不仅判定脑部信息的写权限标志外,还要判定一个临时的锁文件是否可以得到,假如可以得到,则虽然腹部信息的写权限标志为1(上述),也可以启动写权限,虽然这早已表明写权限获得的应用已然异常退出,这段代码如下://打开一个临时的文件,注意同一共享显存,该文件名要相同,可以在共享文件名后加后缀".lock"。RandomAccessFilefis=newRandomAccessFile("shm.lock","rw");//获得文件通道FileChannellockfc=fis.getChannel();//获得文件的独占锁,该方式不形成堵塞,立即返回FileLockflock=lockfc.tryLock();//假如为空,则表明早已有应用占有该锁if(flock==null){.//不能执行写操作}else{.//可以执行写操作}该锁会在应用异常退出后手动释放,这正是该处所须要的方式。发表于@2010年06月08日15:19:00|||