当我在开发一款关于音频通讯的sdk时通过搜集的资料,观看大神的博客,以及再加上个人的见解实现的环形缓冲区,思路是生产者消费者模式,用的是阻塞式队列BlockingQueue(详情参见http://blog.****.net/zlb824/article/details/7091814),我的buffer代码
/* * Copyright (C) 2013 liujian * * Licensed under the GPL License Version 2.0; * you may not use this file except in compliance with the License. * * If you have any question, please contact me. * ************************************************************************* ** Author information ** ************************************************************************* ** Email: 1187502892@qq.com ** ** QQ :<span style="font-family: Arial, Helvetica, sans-serif;">1187502892</span> ************************************************************************* */ package com.zhifutong.zhangxinbao.tool; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; public class Buffer { private final static String TAG = "Buffer"; private BlockingQueue<BufferData> mProducerQueue; private BlockingQueue<BufferData> mConsumeQueue; private int mBufferCount; private int mBufferSize; public static BufferData mBufferData = new BufferData( Global.bufferSizeInBytes); // when mData is null, means it is end of input public static class BufferData { public byte mData[]; private int mFilledSize; private int mMaxBufferSize; private static BufferData sEmptyBuffer = new BufferData(0); public BufferData(int maxBufferSize) { mMaxBufferSize = maxBufferSize; reset(); if (maxBufferSize > 0) { mMaxBufferSize = maxBufferSize; mData = new byte[mMaxBufferSize]; } else { mData = null; } } public static BufferData getEmptyBuffer() { return sEmptyBuffer; } final public void reset() { mFilledSize = 0; } final public int getMaxBufferSize() { return mMaxBufferSize; } final public void setFilledSize(int size) { mFilledSize = size; } final public int getFilledSize() { return mFilledSize; } } public Buffer() { this(3, Global.bufferSizeInBytes); } public Buffer(int bufferCount, int bufferSize) { mBufferSize = bufferSize; mBufferCount = bufferCount; mProducerQueue = new LinkedBlockingQueue<BufferData>(mBufferCount); // we want to put the end buffer, so need to add 1 mConsumeQueue = new LinkedBlockingQueue<BufferData>(mBufferCount); for (int i = 0; i < mBufferCount; ++i) { try { mProducerQueue.put(new BufferData(mBufferSize)); } catch (InterruptedException e) { e.printStackTrace(); } } } public void reset() { int size = mProducerQueue.size(); for (int i = 0; i < size; ++i) { BufferData data = mProducerQueue.peek(); if (null == data || null == data.mData) { mProducerQueue.poll(); } } size = mConsumeQueue.size(); for (int i = 0; i < size; ++i) { BufferData data = mConsumeQueue.poll(); if (null != data && null != data.mData) { mProducerQueue.add(data); } } // LogHelper.d(TAG, "reset ProducerQueue Size:" + mProducerQueue.size() // + " ConsumeQueue Size:" + mConsumeQueue.size()); } final public int getEmptyCount() { return mProducerQueue.size(); } final public int getFullCount() { return mConsumeQueue.size(); } public BufferData getEmpty() { // try { // if (mProducerQueue.size() == 0) { // for (int i = 0; i < mBufferCount; i++) { // mProducerQueue // .put(new BufferData(Global.bufferSizeInBytes)); // } // } // // } catch (InterruptedException e1) { // // TODO Auto-generated catch block // e1.printStackTrace(); // } return getImpl(mProducerQueue); } public boolean putEmpty(BufferData data) { return putImpl(data, mProducerQueue); } public BufferData getFull() { return getImpl(mConsumeQueue); } public boolean putFull(BufferData data) { return putImpl(data, mConsumeQueue); } private BufferData getImpl(BlockingQueue<BufferData> queue) { if (null != queue) { try { return queue.take(); } catch (InterruptedException e) { e.printStackTrace(); } } return null; } private boolean putImpl(BufferData data, BlockingQueue<BufferData> queue) { if (null != queue && null != data) { try { queue.put(data); return true; } catch (InterruptedException e) { e.printStackTrace(); } } return false; } }上面代码能够实现简单的环形缓冲区的角色,
把消费者用过的data在放入生产这种循环利用。