内存共享就是对同一段内存的读写;用来进行进程之间的通信。
首先是写的代码:
package com.sharememory.test;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
public class WriteMemory {
String fileName = "shm.lock";
RandomAccessFile raFile;
FileChannel fc;
int iSize = 1024;
MappedByteBuffer mapBuf;
int iMode;
public WriteMemory() {
try {
init();
} catch (Exception e) {
e.printStackTrace();
}
}
public void init() throws Exception {
raFile = new RandomAccessFile(fileName, "rw");
fc = raFile.getChannel();
mapBuf = fc.map(FileChannel.MapMode.READ_WRITE, 0, iSize);
}
public void clearBuffer() {
// 清除文件内容
for (int i = 0; i < 1024; i++) {
mapBuf.put(i, (byte) 0);
}
}
public void putBuffer() throws Exception{
for (int i = 65; i < 91; i++) {
int index = i - 63;
int flag = mapBuf.get(0); // 可读标置第一个字节为 0
if (flag != 0) { // 不是可写标示 0,则重复循环,等待
i--;
continue;
}
mapBuf.put(0, (byte) 1); // 正在写数据,标志第一个字节为 1
mapBuf.put(1, (byte) (index)); // 写数据的位置
System.out.println("程序 WriteShareMemory:"
+ System.currentTimeMillis() + ":位置:" + index + " 写入数据:"
+ (char) i);
mapBuf.put(index, (byte) i);// index 位置写入数据
mapBuf.put(0, (byte) 2); // 置可读数据标志第一个字节为 2
Thread.sleep(513);
}
}
public boolean getLock() {
FileLock lock = null;
try {
lock = fc.tryLock();
} catch (IOException e) {
e.printStackTrace();
}
if (lock == null) {
return false;
} else {
return true;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
WriteMemory map = new WriteMemory();
if (map.getLock()) {
try {
map.putBuffer();
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.out.println("can't get lock");
}
}
}
然后是读的代码
package com.sharememory.test;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
public class ReadMemory {
String fileName = "shm.lock";
RandomAccessFile raFile;
FileChannel fc;
int iSize = 1024;
MappedByteBuffer mapBuf;
int iMode;
int lastIndex = 0;
public ReadMemory() {
try {
init();
} catch (Exception e) {
e.printStackTrace();
}
}
public void init() throws Exception {
raFile = new RandomAccessFile(fileName, "rw");
fc = raFile.getChannel();
mapBuf = fc.map(FileChannel.MapMode.READ_WRITE, 0, iSize);
}
public void clearBuffer() {
// 清除文件内容
for (int i = 0; i < 1024; i++) {
mapBuf.put(i, (byte) 0);
}
}
public void getBuffer() throws Exception{
for(int i=1;i<27;i++){
int flag = mapBuf.get(0); //取读写数据的标志
int index = mapBuf.get(1); //读取数据的位置,2 为可读
if(flag != 2 || index == lastIndex){ //假如不可读,或未写入新数据时重复循环
i--;
continue;
}
lastIndex = index;
System.out.println("程序 ReadShareMemory:" + System.currentTimeMillis() +
":位置:" + index +" 读出数据:" + (char)mapBuf.get(index));
mapBuf.put(0,(byte)0); //置第一个字节为可读标志为 0
if(index == 27){ //读完数据后退出
break;
}
}
}
public boolean getLock() {
FileLock lock = null;
try {
lock = fc.tryLock();
} catch (IOException e) {
e.printStackTrace();
}
if (lock == null) {
return false;
} else {
return true;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ReadMemory map = new ReadMemory();
if (map.getLock()) {
try {
map.getBuffer();
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.out.println("can't get lock");
}
}
}
上面代码一个先运行的时候,会上锁(文件锁),另外其他的进程来访问的时候就访问不了,通过锁的机制来达到资源互斥和同步。
分享到:
相关推荐
一个进程可以包含多个线程,它们共享同一内存空间,这减少了线程间通信的开销。相比进程,线程更轻量级,调度更快,但同时也带来了线程安全问题,因为它们共享数据。 **二、创建Java线程** 在Java中,创建线程主要...
8. **静态成员**:静态成员属于类本身,而非类的实例,这意味着它们在内存中只有一份拷贝,所有类的实例共享这些静态成员。 9. **this关键字**:this代表当前对象的引用,常用于区分实例变量和局部变量,以及在构造...
- **示例**: 使用`Thread`类或实现`Runnable`接口创建线程,利用`synchronized`关键字控制同步访问共享资源。 #### 三、Java语言发展历程 2005年6月,SUN公司在JavaOne大会上宣布了Java的各种版本名称变更: - ...
9. **Java内存模型** - **JMM(Java Memory Model)**:理解JMM对于理解线程间的数据可见性和有序性至关重要,它规定了线程如何访问和修改共享变量。 10. **线程安全问题** - **竞态条件**:当多个线程并发访问和...
Sun Microsystems(现已被Oracle收购)是Java技术的原创者,其制定的Java虚拟机规范是理解JVM工作原理的权威来源。这个规范详细阐述了JVM如何解析、执行Java字节码,以及内存管理、类加载机制、异常处理等多个关键...
- **图像资源加载**:游戏中的图片资源被加载到内存中,显示在GUI上,这需要用到Java的图像处理类,如`BufferedImage`。 3. **游戏逻辑**: - **鱼的生成与移动**:随机生成不同种类的鱼,它们有不同的移动速度和...
Java虚拟机(JVM)是运行Java程序的平台,架构师需要了解JVM的内存模型,包括线程私有的区域如程序计数器、虚拟机栈、本地方法栈,以及线程共享的堆和方法区。对于JVM的运行时内存,需要掌握新生代、老年代以及永久...
将堆和栈分离,可以实现更好的内存管理和性能优化,比如多线程共享数据、动态对象大小调整等。 堆中存储的是对象,而栈中存储基本数据类型和对堆中对象的引用。一个对象在堆中的大小是可变的,而栈中仅保存对象的4...
- 享元模式(Flyweight):运用共享技术有效地支持大量细粒度的对象,减少内存开销。 3. 行为型模式: - 模板方法模式(Template Method):定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以...
a) **Terracotta**:通过Terracotta服务器,Ehcache可以实现跨JVM的缓存共享,提供透明的分布式缓存功能。 b) **RMI (Remote Method Invocation)**:利用RMI协议,实现远程节点间的缓存同步。 c) **JMS (Java...
Java 2 Micro Edition (J2ME) 是Java平台的一个子集,主要用于嵌入式设备和移动设备,如早期的智能手机和功能手机。它提供了开发和部署小型应用程序(通常称为MIDlet)的能力,其中就包括了游戏。J2ME以其跨平台性、...
happens-before原则是Java内存模型中定义的两项操作之间的偏序关系,如果说操作A先行发生于操作B,其实就是说在发生操作B之前,操作A产生的影响能被操作B观察到。“影响”包括修改了内存中共享变量的值、 发送了消息...
- **资源池化**:集群内的资源(如内存、线程等)可以被所有成员共享,提高了资源利用率。 2. **WebLogic相关概念详解** - **域(DOMAIN)**:域是WebLogic Server管理的最小单位,包含一个或多个服务器实例,以及...
`ArrayList`是一个动态数组的实现,其主要功能是在内存中存储一个可变大小的对象数组。它位于`java.util`包内,并且继承自`AbstractList`抽象类,同时实现了多个接口:`List`、`RandomAccess`、`Cloneable`及`...
在实际项目中,使用ForkNDK需要考虑的问题包括进程间的内存隔离(意味着不能直接共享内存)、数据同步和错误处理等。此外,由于原生进程的创建和销毁都需要消耗资源,因此在设计时应尽可能优化进程生命周期管理,...
SGA是Oracle数据库运行时的一个内存结构,包含了多个组件,如数据缓冲区缓存、共享池、大型池、Java池等。在示例中,`sga_target`和`sga_max_size`是控制SGA总大小的参数。`sga_target`用于自动管理SGA各个组件的...
3. Session管理:合理设置session过期时间,避免内存泄漏,可能结合Redis等缓存系统优化session共享。 4. 数据库索引:为频繁查询的字段建立索引,提高查询效率。 五、测试与部署 1. 单元测试:JUnit或Mockito进行...
IPC技术包括管道(Pipes)、信号量(Semaphores)、消息队列(Message Queues)和共享内存(Shared Memory)等。 多线程是一种编程方法,允许多个线程在单个进程的地址空间中执行任务,这样可以利用多核CPU的计算...
匿名共享内存分析的也很好。 情况分析应该是学毛德操老师的,作者确实做到了,作者在讲解时,会从java层到native层,再到linux kernel中整个串起来讲。使读者可以完全了解某些子系统的运行机制 内容简介 · · · ...
匿名共享内存分析的也很好。 情况分析应该是学毛德操老师的,作者确实做到了,作者在讲解时,会从java层到native层,再到linux kernel中整个串起来讲。使读者可以完全了解某些子系统的运行机制 内容简介 · · · ...