先说说遇到的问题是什么情况,一般我们在编程的时候,遇到的数据量都是可以量级的,cpu压力并不是太大,比如一个小时一次请求服务器获取时间来进行校验,一分钟获取一下wifi设备的信息更新下状态,或者一秒钟获取一下接受目标设备传过来的有效信息,很少出现秒以下的量级;然后就这样写着写着就遇到问题了,现在从蓝牙设备终端获取数据频率是30ms一次,一次大概传输一百多,或者两百多字节,这种按照以前的传输方式传输的话很容易卡死,用了各种办法,把缓冲区从一个换成两个,然后又把缓冲区从两个换成三个才解决问题,当然思想上单线程顺序执行已经不行了,然后就用双缓冲交替接受数据才跟的上速度。
这种问题一般遇不到,但是对速度要求高的地方可能会用的比较多点,双缓冲设计只是一种思想,并不是一种硬性的编程规范,就类似于面向对象的思想,其实并没有很严格的限制,当然如果遇到一个大点的公司讲究编程规范的时候可能会有点要求。
下面献上代码:
//two buffers to save data
int BUFFER_LENGTH = 800;
byte[] mBuffer1 = new byte[BUFFER_LENGTH];
int mBuffer1Pointer = 0;
byte[] mBuffer2 = new byte[BUFFER_LENGTH];
int mBuffer2Pointer = 0;
boolean mFlagWrite;//flag to switch buffer
byte[] mLargeTargetArray = new byte[10 * 1000];
//deal data,bytes: source array, i: effective data's index
public void dealReceiveData(byte[] bytes, int i) {
/*copy bytes' effective data to mLargeTargetArray, in this way, improve effectivity to solve datas,
this function was called frequently */
}
public void readData(InputStream in)
{
//two buffers to get data
if (!mFlagWrite) {
try {
mBuffer1Pointer = in.read(mBuffer1, 0, mBuffer1.length - 20);
} catch (IOException e) {
e.printStackTrace();
}
if (mBuffer1Pointer >= 100) {
mFlagWrite = !mFlagWrite;
dealReceiveData(mBuffer1, mBuffer1Pointer);
mBuffer1Pointer = 0;
}
} else {
try {
mBuffer2Pointer = in.read(mBuffer2, 0, mBuffer2.length - 20);
} catch (IOException e) {
e.printStackTrace();
}
if (mBuffer2Pointer >= 100) {
mFlagWrite = !mFlagWrite;
dealReceiveData(mBuffer2, mBuffer2Pointer);
mBuffer2Pointer = 0;
}
}
}
稍微做一点讲解基本上就理解了:readData这个方法的执行频率大概几十毫秒一次,从stream中读取数据,然后通过mFlagWrite作为一个标记,如果mFlagWrite是true,就读进mBuffer2缓冲区里面,然后mFlagWrite取反为false,并把mBuffer2缓冲区里面的内容通过dealReceiveData复制到mLargeTargetArray里面,之后重置写的指针下标,下次在访问这个方法时,mFlagWrite是false,所以就开始操作mBuffer1,并对mBuffer1做与mBuffer2相同的操作,如此交替执行读写就可以大幅度提高传输效率。
mBuffer2和mBuffer1的大小要根据实际情况来确定不能太小,太大也不好,浪费资源,需要注意的是这两个缓冲区只负责接收数据,最后的大缓冲区才负责根据各种业务逻辑做出相应的操作和判断。