- 浏览: 261920 次
- 性别:
- 来自: 多伦多
文章分类
- 全部博客 (127)
- Java 基础 (46)
- Java EE (3)
- Clouds (1)
- Spring 编程 (7)
- Spring Batch 编程 (1)
- Quartz 编程 (9)
- Seam 编程 (4)
- Hibernate 编程 (1)
- JSF 编程 (3)
- jQuery 编程 (3)
- Interview Question 汇总 (3)
- 日常应用 (3)
- Maven 编程 (2)
- WebService 编程 (10)
- Scala 编程 (5)
- Coherence 编程 (8)
- OO 编程 (1)
- Java 线程 (6)
- DB 编程 (2)
- WebService 安全 (4)
- Oracle Fusion 编程 (2)
- JavsScript/Ajax 编程 (1)
最新评论
-
chainal:
赞,说的很好
Scala 有趣的Trait -
wuliupo:
RRRR-MM-DD HH24:MI:SS
如何让Oracle SQL Developer显示的包含在日期字段中的时间 -
pengain:
...
使用Spring Roo ,感受ROR式的开发 -
zeng1990:
def getPersonInfo() = {
(&quo ...
Java 的继位人? - Scala简介 -
zeng1990:
我使用的是2.9.2版本的!
Java 的继位人? - Scala简介
(转自 http://www.builder.com.cn/2008/0424/831162.shtml)
对熟知UNIX系统应用开发的程序员来说,IPC(InterProcess Communication)机制是非常熟悉的,IPC基本包括共享内存、信号灯操作、消息队列、信号处理等部分,是开发应用中非常重要的必不可少的工具。其中共享内存IPC机制的关键,对于数据共享、系统快速查询、动态配置、减少资源耗费等均有独到的优点。
对应UNIX系统来说,共享内存分为一般共享内存和映像文件共享内存两种,而对应 Windows,实际上只有映像文件共享内存一种。所以java应用中也是只能创建映像文件共享内存。
在java语言中,基本上没有提及共享内存这个概念,但是,在某一些应用中,共享内存确实非常有用,例如采用java语言的分布式应用系统中,存在着大量的分布式共享对象,很多时候需要查询这些对象的状态,以查看系统是否运行正常或者了解这些对象的目前的一些统计数据和状态。如果采用网络通信的方式,显然会增加应用的额外负担,也增加了一些不必要的应用编程。而如果采用共享内存的方式,则可以直接通过共享内存查看对象的状态数据和统计数据,从而减少了一些不必要的麻烦。
共享内存的使用有如下几个特点:
可以被多个进程打开访问;
读写操作的进程在执行读写操作时其他进程不能进行写操作;
多个进程可以交替对某一共享内存执行写操作;
一个进程执行了内存的写操作后,不影响其他进程对该内存的访问。同时其他进程对更新后的内存具有可见性。
在进程执行写操作时如果异常退出,对其他进程写操作禁止应自动解除。
相对共享文件,数据访问的方便性和效率有
另外,共享内存的使用上有如下情况:
独占的写操作,相应有独占的写操作等待队列。独占的写操作本身不会发生数据的一致性问题。
共享的写操作,相应有共享的写操作等待队列。共享的写操作则要注意防止发生数据的一致性问题。
独占的读操作,相应有共享的读操作等待队列;
共享的读操作,相应有共享的读操作等待队列。
一般情况下,我们只是关心第一二种情况。
2 共享内存在java中的实现
在jdk1.4中提供的类MappedByteBuffer为我们实现共享内存提供了较好的方法。该缓冲区实际上是一个磁盘文件的内存映像。二者的变化将保持同步,即内存数据发生变化会立刻反映到磁盘文件中,这样会有效的保证共享内存的实现。
将共享内存和磁盘文件建立联系的是文件通道类:FileChannel。该类的加入是JDK为了统一对外部设备(文件、网络接口等)的访问方法,并且加强了多线程对同一文件进行存取的安全性。例如读写操作统一成read和write。这里只是用它来建立共享内存用,它建立了共享内存和磁盘文件之间的一个通道。
打开一个文件建立一个文件通道可以用RandomAccessFile类中的方法getChannel。该方法将直接返回一个文件通道。该文件通道由于对应的文件设为随机存取文件,一方面可以进行读写两种操作,另一方面使用它不会破坏映像文件的内容(如果用FileOutputStream直接打开一个映像文件会将该文件的大小置为0,当然数据会全部丢失)。这里,如果用 FileOutputStream和FileInputStream则不能理想的实现共享内存的要求,因为这两个类同时实现自由的读写操作要困难得多。
下面的代码实现了如上功能,它的作用类似UNIX系统中的mmap函数。
// 获得一个只读的随机存取文件对象
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);
// 获取头部消息:存取权限
mode = mapBuf.getInt();
如果多个应用映像同一文件名的共享内存,则意味着这多个应用共享了同一内存数据。这些应用对于文件可以具有同等存取权限,一个应用对数据的刷新会更新到多个应用中。
为了防止多个应用同时对共享内存进行写操作,可以在该共享内存的头部信息加入写操作标志。该共享内存的头部基本信息至少有:
int Length; // 共享内存的长度。
int mode; // 该共享内存目前的存取模式。
共享内存的头部信息是类的私有信息,在多个应用可以对同一共享内存执行写操作时,开始执行写操作和结束写操作时,需调用如下方法:
public boolean StartWrite() { if(mode == 0) { // 标志为0,则表示可写 mode = 1; // 置标志为1,意味着别的应用不可写该共享内存 mapBuf.flip(); mapBuf.putInt(mode); // 写如共享内存的头部信息 return true; } else { return false; // 指明已经有应用在写该共享内存,本应用不可写该共享内存 } } public boolean StopWrite() { mode = 0; // 释放写权限 mapBuf.flip(); mapBuf.putInt(mode); // 写入共享内存头部信息 return true; } |
如果执行写操作的应用异常中止,那么映像文件的共享内存将不再能执行写操作。为了在应用异常中止后,写操作禁止标志自动消除,必须让运行的应用获知退出的应用。在多线程应用中,可以用同步方法获得这样的效果,但是在多进程中,同步是不起作用的。方法可以采用的多种技巧,这里只是描述一可能的实现:采用文件锁的方式。写共享内存应用在获得对一个共享内存写权限的时候,除了判断头部信息的写权限标志外,还要判断一个临时的锁文件是否可以得到,如果可以得到,则即使头部信息的写权限标志为1(上述),也可以启动写权限,其实这已经表明写权限获得的应用已经异常退出,这段代码如下:
// 打开一个临时的文件,注意同一共享内存,该文件名要相同,可以在共享文件名后加后缀“.lock”。 RandomAccessFile fis = new RandomAccessFile("shm.lock","rw"); // 获得文件通道 FileChannel lockfc = fis.getChannel(); // 获得文件的独占锁,该方法不产生堵塞,立刻返回 FileLock flock = lockfc.tryLock(); // 如果为空,则表明已经有应用占有该锁 if(flock == null) { ...// 不能执行写操作 } else { ...// 可以执行写操作 } |
3 共享内存在java中的应用
共享内存在java应用中,经常有如下两种种应用:
永久对象配置。
在java服务器应用中,用户可能会在运行过程中配置一些参数,而这些参数需要永久有效,当服务器应用重新启动后,这些配置参数仍然可以对应用起作用。这就可以用到该文中的共享内存。该共享内存中保存了服务器的运行参数和一些对象运行特性。可以在应用启动时读入以启用以前配置的参数。
查询共享数据。
一个应用(例 sys.java)是系统的服务进程,其系统的运行状态记录在共享内存中,其中运行状态可能是不断变化的。为了随时了解系统的运行状态,启动另一个应用(例 mon.java),该应用查询该共享内存,汇报系统的运行状态。
可见,共享内存在java应用中还是很有用的,只要组织好共享内存的数据结构,共享内存就可以在应用开发中发挥很不错的作用。
发表评论
-
设计模式之事务处理
2010-11-25 07:36 912转自 http://www.blogjava.net/kill ... -
设计自己的MVC框架(1)
2010-11-25 07:27 1251转自 http://www.blogjava.net/ ... -
设计自己的MVC框架(2)
2010-11-25 07:24 1178转自 http://www.blogjava.ne ... -
使用Annotation设计持久层
2010-11-25 06:59 956(From http://www.blogjava. ... -
Jakarta Commons StringUtils类使用
2010-11-25 06:58 935转自http://www.blogjava.net/ ... -
Jakarta Commons ArrayUtils类使用
2010-11-25 06:57 1132转自http://www.blogjava.net/ ... -
Reflection的三个动态性质
2010-11-25 06:56 1013转自http://www.blogjava. ... -
用commons.fileupload实现文件的上传和下载
2010-11-25 06:55 1401转自http://www.blogjav ... -
JAVA变量类型之间的相互转换
2010-11-25 06:52 899(转自 http://www.builder.c ... -
优秀Java程序员必须了解的GC工作原理
2010-11-25 06:52 888(转自 http://www.build ... -
几种版权信息详解
2010-11-25 06:49 1132BSD开源协议(original ... -
Java JDK 1.4 JCE Provider issue.
2010-11-25 06:48 1175Bundled JCE provider in jdk1 ... -
Why use Map.entrySet() instead of Map.keySet()?
2010-11-25 06:45 1393(From http://www.coderan ... -
Credit Card Mod10 校验
2010-11-25 06:27 2076以下是几种Mod10的实现。第一种最为简洁,最后一种 ... -
如何知道方法的调用者
2010-11-25 05:57 7399转自http://hellboys.bok ... -
Java加解密的基础
2010-11-25 05:49 2821在Java的安全包中,包括了三部分内容: ... -
Java日志框架:SLF4J, Apache Common-Logging, Log4J和Logback
2010-11-25 05:47 1858Log4j Apache的一个开放源代码项目,通过 ... -
Java SE 6新特性:Instrumentation
2010-11-25 05:35 1076(转自http://baike.baidu.com ... -
JBOSS 启动 加载 过程
2010-09-11 00:26 3024(转自: http://blog.csdn.net/ylli_ ... -
JAVA性能优化—Sun Hotspot JDK JVM参数设置
2010-09-11 00:18 1206(转自: http://www.hashei.me/2009/ ...
相关推荐
共享内存在Java中的实现和应用.doc
综上所述,JAVA实现局域网桌面共享涉及到网络编程、多线程、图像处理、数据传输协议等多个领域,而项目中提及的线程优化问题需要进一步关注和改进。通过不断优化和调试,这个应用可以变得更加健壮和高效。
分布式Java应用基础与实践是Java开发领域中的一个重要主题,它涉及到如何通过网络将多个独立的计算机节点连接起来,协同处理任务,以实现系统的高可用性、高性能和可伸缩性。在Java中,分布式系统主要依赖于一些核心...
分布式Java应用:基础与实践 在当今的互联网时代,分布式系统已经成为企业级应用程序开发的...《分布式java应用:基础与实践》这本书正是为此目的而编写,旨在为Java开发者提供全面的分布式系统理论知识和实践经验。
本项目“java远程屏幕共享程序(局域网)”就是这样一个实现,它采用Java编程语言,提供了客户端(Client.jar)和服务器端(Server.jar)两个组成部分,适合于局域网内的设备间进行屏幕共享。以下将详细解析这个项目...
通过阅读这本书,开发者不仅能理解JVM的基本运作机制,还能掌握如何利用这些知识来优化Java应用,提升程序性能,解决实际开发中的问题。对于Java开发者来说,理解JVM的工作原理是提升技术水平和解决问题的关键步骤。
在Java编程环境中,有时我们需要与Windows操作系统进行交互,例如访问共享目录并下载其中的文件。这个过程涉及到几个关键的技术点,包括系统调用、网络通信和文件操作。在这个场景下,我们将通过`SmbUtils.java`和`...
总的来说,这个JAVA实现的屏幕共享程序利用了JAVA的多线程、图形处理和网络编程功能,结合UDP协议,为局域网内的用户提供了一种简单的屏幕共享解决方案。对于开发者来说,这是一个很好的学习和实践JAVA网络编程、...
Java 局域网文件共享程序是一种利用Java编程语言开发的应用,旨在实现局域网内的文件共享、下载以及聊天功能。这种程序通常通过网络编程技术,如Socket编程和多线程处理,来实现在同一网络环境下的设备间进行高效的...
分布式JAVA应用基础与实战是Java开发领域中的一个重要话题,它涉及到如何通过网络将多个独立的计算机节点连接起来,协同处理任务,以实现系统的高可用性、高性能和可伸缩性。这一主题通常涵盖多个关键知识点,包括但...
本篇将深入探讨分布式Java应用的基础知识和实践要点,通过源码分析帮助读者理解如何构建和优化分布式系统。 1. 分布式系统概念 分布式系统是由多个相互协作的计算机节点组成的网络系统,这些节点通过网络通信,共享...
在Java编程环境中,处理共享文件是一项常见的任务,特别是在企业级应用中,可能需要访问网络上的文件系统资源。Java提供了一些库来实现这一功能,其中之一就是jcifs库,它是一个开源的Java SMB(Server Message ...
- JRE(Java Runtime Environment)包含了JVM和Java的核心类库,提供了运行Java应用程序的环境。 - JDK(Java Development Kit)是开发工具包,包括JRE和一系列开发工具,如编译器、调试器等。 2. 环境变量: - ...
这篇博客文章可能详细解释了如何在Java环境中实现对远程文件系统的访问,以便读取、写入或管理共享文件。 在Java中,可以使用开源库如jcifs(Java CIFS Client)来处理SMB/CIFS协议。jcifs库提供了SmbFile类,它...
本文详细介绍了如何使用Java语言结合jcifs库操作Windows共享目录的方法,主要包括了SMB协议的基本概念及其在Windows系统中的应用,以及jcifs库的功能特点和具体使用示例。通过对这些内容的学习,开发者可以更好地...
Java 软件设计基础:Java线程机制 Java 软件设计基础中,Java 线程机制是指在 Java ...Java 线程机制是 Java 软件设计基础中的一个重要组成部分,它提供了实现多线程编程的机制,从而提高了系统的并发能力和响应速度。
Java的设计目标是具有高度的可移植性、安全性以及健壮性,这使得它成为开发跨平台应用程序的理想选择。Java的基础核心是其语法、类库以及运行时环境(Java虚拟机JVM)。本学习笔记将深入探讨Java的核心概念,帮助你...
分布式JAVA应用基础与实践是Java开发领域中一个重要的主题,主要涵盖了如何在大规模网络环境中设计、部署和管理Java应用程序。本书由林昊编著,旨在帮助开发者深入理解分布式系统的基本概念,掌握Java在分布式环境中...
【Java源码:赛马游戏】是一个非常适合初学者学习的编程项目,它涵盖了Java语言的基础知识,以及如何在Eclipse或MyEclipse等集成开发环境中部署和运行Java应用程序。通过这个项目,我们可以深入理解面向对象编程的...
【Java项目:贪吃蛇游戏(java+...通过这个项目,开发者不仅可以巩固Java编程基础,还能深入理解Swing库的使用,提高图形界面设计和游戏开发能力。同时,这也是一个很好的练习项目,能锻炼问题解决、逻辑思维和调试技能。