用java实现环形缓冲池功能

最近我在学习操作系统这本书。操作系统实现了应用程序和硬件的连接,属于硬件和用户程序之间的接口。对资源的管理和对进程的调度执行是操作系统的核心。为了解决IO设备的存取速度和CPU对数据处理速度的不匹配的问题,设计师引入了缓冲区这一个概念。将IO的数据先存放在缓冲池,存放到一定数目时将其传入内存交由CPU进行处理。所以我想用java语言来简要实现一下我个人对环形缓冲区的理解。

首先我想简要介绍一下什么是环形缓冲池。顾名思义,就是由若干个缓冲池组成的一个循环队列。数据可以放入这些缓冲器或者从里面取出,然后再将数据放入空的缓冲区中。为了方便我们的使用和管理,在此引入了三个指针。

public Integer nextg;//下一个可用的缓冲区,即其中的数据可以被进程使用
public Integer nexti;//下一个空的缓冲区
public Integer current;//当前正在使用的缓冲区

缓冲区中我也设置了一个属性,用来表示该缓冲区的情况。

/**
 * 设置该缓冲区的状态.0表示为空。1表示包含数据可以被操作.2表示正在数据被进程使用
 */
public Integer status = 0;

当然我们还需要三个功能。一个是实现数据传入缓冲区,另一个是将数据从缓冲区中取出来交给进程进行处理,还有一个就是清空缓冲区。

下面我想对我的算法进行一个简要的解释。

首先使用一个有参构造函数,入参为缓冲区的个数,将nextg和nexti的值设为0,将current的值设为null。

下面我来介绍我的将数据传入缓冲区的函数。putBuf(Object o),其中的入参为传入该缓冲区的内容。传入一个数据后,确认nexti的值,如果为null,则令它等于nextg的值。因为这说明在传入该数据之前,这个环形缓冲区没有数据(这是我的算法的设定)。之后nextg进行遍历找到下一个空的缓冲区,并更改指针值。

然后是getBuf(),这个函数是从nexti指向的缓冲区中进行取值,然后让current的值指向nexti。修改缓冲区的status属性为2,表示正在使用中。待数据处理完之后,调用releaseBuf(Integer current)函数。

关于releaseBuf(Integer current)函数,这个构思很简单。只有三行代码。

this.mbArray[current].data =null;
	this.mbArray[current].status = 0;
	this.nexti = this.current;//当前缓冲区设置为下一个可以使用的空缓冲区

下面是我的算法的完整代码

由于是第一次,可能会有一些问题,欢迎大家指正。

package com.xt.myos.iotest.bufferingpool.test;

import com.xt.myos.iotest.bufferingpool.util.MyBuffer;

public class MyCircleBuffer {
public Integer nextg;//下一个可用的缓冲区,即其中的数据可以被进程使用
public Integer nexti;//下一个空的缓冲区
public Integer current;//当前正在使用的缓冲区
public int maxsize;//缓冲区的个数
public MyBuffer[] mbArray;

public MyCircleBuffer(int maxsize) {
	super();
	mbArray = new MyBuffer[maxsize];//将缓冲区初始化
	for(int i=0;i<maxsize;i++){
		MyBuffer mb = new MyBuffer();
		mb.rank = i;
		mb.data=null;
		mbArray[i] = mb;
	}
	this.maxsize = maxsize;
	this.current=null;
	this.nexti=0;
	this.nextg = 0;//
}
/**
 * 选取下一个空缓冲区存放内容
 * @throws Exception 
 */
public boolean putBuf(Object o) throws Exception{
	if(this.nexti==null){
		throw new Exception("所有缓冲区已满,不能在存放数据");
	}
	mbArray[this.nexti].data = o;//存放的内容
	mbArray[this.nexti].status = 1;//将该缓冲区修改成当前的数据可以被访问
	//如果nextg的值为null,说明在放入该数据之前原缓冲区数组为空,将执行this.nexti = this.nextg
	if(this.nextg==null){
		this.nextg = this.nexti;
	}
	//从该空缓冲区向后检索,直到发现第一个空缓冲区退出该函数
	for(int i=this.nexti;i<this.maxsize;i++){
		if(mbArray[i].status==0){
			this.nexti = i;
			return true;
		}
	}
	//如果该缓冲区向后无缓冲区,则从缓冲区数组最开始进行检索
	for(int i=0;i<this.nexti;i++){
		if(mbArray[i].status==0){
			this.nexti = i;
			return true;
		}
	}
	this.nexti = null;
	return false;
}
/**
 * 从nexti指向的缓冲区中获取数据
 * @return
 * @throws Exception
 */
public boolean getBuf() throws Exception{
	if(this.nextg==null){
		throw new Exception("没有可以获取数据的缓冲区,内容获取失败");
	}
	if(this.mbArray[this.nextg].data==null){
		throw new Exception("该缓冲区没有内容,内容获取失败");
	}
	this.mbArray[this.nextg].status = 2;//要提取该缓冲区的数据时,将该缓冲区的状态设置为2
	this.current = this.nextg;//让当前工作的缓存指针指向nexti
	System.out.println("现在将  "+this.mbArray[this.current].rank+"号缓冲区内的内容:   "+this.mbArray[this.nexti].data+"交给进程进行处理");
	System.out.println("当前正在提取数据的缓冲区是: "+this.mbArray[this.current].rank);
	releaseBuf(this.current);
	for(int i=this.nextg;i<this.maxsize;i++){
		if(mbArray[i].status==1){
			this.nextg = i;
			return true;
		}
	}
	for(int i=0;i<this.nextg;i++){
		if(mbArray[i].status==1){
			this.nextg = i;
			return true;
		}
	}
	this.nextg=null;
	return false;
}
/**
 * 将指定的缓冲区的内容设置为null
 * @param current
 * @return
 */
public boolean releaseBuf(Integer current){
	this.mbArray[current].data =null;
	this.mbArray[current].status = 0;
	this.nexti = this.current;//当前缓冲区设置为下一个可以使用的空缓冲区
	return true;
}
@Override
public String toString() {
	return "下一个可用缓冲区G是: "+nextg+" \n"
			+"下次可用的空缓冲区R是: "+nexti+" \n"
			+"指示计算进程正在使用的缓冲区C的指针: "+current;
}


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值