`

【原创】Java实现内存共享

    博客分类:
  • Java
阅读更多
内存共享就是对同一段内存的读写;用来进行进程之间的通信。

首先是写的代码:
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线程实例讲解【原创】.pdf

    一个进程可以包含多个线程,它们共享同一内存空间,这减少了线程间通信的开销。相比进程,线程更轻量级,调度更快,但同时也带来了线程安全问题,因为它们共享数据。 **二、创建Java线程** 在Java中,创建线程主要...

    JavaOOP_第9章上机练习.zip

    8. **静态成员**:静态成员属于类本身,而非类的实例,这意味着它们在内存中只有一份拷贝,所有类的实例共享这些静态成员。 9. **this关键字**:this代表当前对象的引用,常用于区分实例变量和局部变量,以及在构造...

    Java 培训教程(千峰教育)

    - **示例**: 使用`Thread`类或实现`Runnable`接口创建线程,利用`synchronized`关键字控制同步访问共享资源。 #### 三、Java语言发展历程 2005年6月,SUN公司在JavaOne大会上宣布了Java的各种版本名称变更: - ...

    多线程精品资源--这是RedSpider社区成员原创与维护的Java多线程系列文章。.zip

    9. **Java内存模型** - **JMM(Java Memory Model)**:理解JMM对于理解线程间的数据可见性和有序性至关重要,它规定了线程如何访问和修改共享变量。 10. **线程安全问题** - **竞态条件**:当多个线程并发访问和...

    java的虚拟机的英文规范

    Sun Microsystems(现已被Oracle收购)是Java技术的原创者,其制定的Java虚拟机规范是理解JVM工作原理的权威来源。这个规范详细阐述了JVM如何解析、执行Java字节码,以及内存管理、类加载机制、异常处理等多个关键...

    捕鱼达人java小游戏源码_含图片资源.rar

    - **图像资源加载**:游戏中的图片资源被加载到内存中,显示在GUI上,这需要用到Java的图像处理类,如`BufferedImage`。 3. **游戏逻辑**: - **鱼的生成与移动**:随机生成不同种类的鱼,它们有不同的移动速度和...

    JAVA架构师知识整理-副本.pdf

    Java虚拟机(JVM)是运行Java程序的平台,架构师需要了解JVM的内存模型,包括线程私有的区域如程序计数器、虚拟机栈、本地方法栈,以及线程共享的堆和方法区。对于JVM的运行时内存,需要掌握新生代、老年代以及永久...

    原创-JVM调优

    将堆和栈分离,可以实现更好的内存管理和性能优化,比如多线程共享数据、动态对象大小调整等。 堆中存储的是对象,而栈中存储基本数据类型和对堆中对象的引用。一个对象在堆中的大小是可变的,而栈中仅保存对象的4...

    原创-设计模式实现代码

    - 享元模式(Flyweight):运用共享技术有效地支持大量细粒度的对象,减少内存开销。 3. 行为型模式: - 模板方法模式(Template Method):定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以...

    Ehcache经典教程实例应用-原创

    a) **Terracotta**:通过Terracotta服务器,Ehcache可以实现跨JVM的缓存共享,提供透明的分布式缓存功能。 b) **RMI (Remote Method Invocation)**:利用RMI协议,实现远程节点间的缓存同步。 c) **JMS (Java...

    J2ME---游戏共享

    Java 2 Micro Edition (J2ME) 是Java平台的一个子集,主要用于嵌入式设备和移动设备,如早期的智能手机和功能手机。它提供了开发和部署小型应用程序(通常称为MIDlet)的能力,其中就包括了游戏。J2ME以其跨平台性、...

    彩虹岛启动器qtga.dll

    happens-before原则是Java内存模型中定义的两项操作之间的偏序关系,如果说操作A先行发生于操作B,其实就是说在发生操作B之前,操作A产生的影响能被操作B观察到。“影响”包括修改了内存中共享变量的值、 发送了消息...

    WebLogic Server11g 集群[原创]

    - **资源池化**:集群内的资源(如内存、线程等)可以被所有成员共享,提高了资源利用率。 2. **WebLogic相关概念详解** - **域(DOMAIN)**:域是WebLogic Server管理的最小单位,包含一个或多个服务器实例,以及...

    ArrayList底层.pdf

    `ArrayList`是一个动态数组的实现,其主要功能是在内存中存储一个可变大小的对象数组。它位于`java.util`包内,并且继承自`AbstractList`抽象类,同时实现了多个接口:`List`、`RandomAccess`、`Cloneable`及`...

    ForkNDK双进程

    在实际项目中,使用ForkNDK需要考虑的问题包括进程间的内存隔离(意味着不能直接共享内存)、数据同步和错误处理等。此外,由于原生进程的创建和销毁都需要消耗资源,因此在设计时应尽可能优化进程生命周期管理,...

    原创文档详细说明ORACLE10G参数文件PFILE与SPFILE

    SGA是Oracle数据库运行时的一个内存结构,包含了多个组件,如数据缓冲区缓存、共享池、大型池、Java池等。在示例中,`sga_target`和`sga_max_size`是控制SGA总大小的参数。`sga_target`用于自动管理SGA各个组件的...

    StuManageSys.zip

    3. Session管理:合理设置session过期时间,避免内存泄漏,可能结合Redis等缓存系统优化session共享。 4. 数据库索引:为频繁查询的字段建立索引,提高查询效率。 五、测试与部署 1. 单元测试:JUnit或Mockito进行...

    达内Unix_Linux 核心编程课件ppt.pdf

    IPC技术包括管道(Pipes)、信号量(Semaphores)、消息队列(Message Queues)和共享内存(Shared Memory)等。 多线程是一种编程方法,允许多个线程在单个进程的地址空间中执行任务,这样可以利用多核CPU的计算...

    Android系统源代码情景分析 PDF 完整版 ZIP.001(二个压缩包)

    匿名共享内存分析的也很好。 情况分析应该是学毛德操老师的,作者确实做到了,作者在讲解时,会从java层到native层,再到linux kernel中整个串起来讲。使读者可以完全了解某些子系统的运行机制 内容简介 · · · ...

    Android系统源代码情景分析 PDF 完整版 ZIP.002(二个压缩包)

    匿名共享内存分析的也很好。 情况分析应该是学毛德操老师的,作者确实做到了,作者在讲解时,会从java层到native层,再到linux kernel中整个串起来讲。使读者可以完全了解某些子系统的运行机制 内容简介 · · · ...

Global site tag (gtag.js) - Google Analytics