优化环形缓冲队列可以从多个方面进行,包括代码可读性、性能以及线程安全性。下面是一些改进建议和相应的代码修改:
状态管理: 可以使用枚举来代替常量,增强代码的可读性。
循环索引: 循环索引的处理可以封装成一个方法,以提高可读性和减少重复代码。
同步控制: 确保在操作共享资源时采取更严格的同步策略,防止潜在的竞争条件。
构造函数: 在
FrameQueue
的构造函数中,可以直接初始化状态为STATUS_READY
。内存管理: 释放帧时,不应该简单地将其状态设置为无效,而应该考虑重置图像内容(如果有必要)。
下面是经过优化后的 FrameQueue
类代码示例:
package com.iroad.physicalsports.tools;
public class FrameQueue {
private Frame[] mQueueBuffer;
private int mQueueBufferSize;
private int mCurrentFreeBufferIndex = -1;
private int mCurrentUsingBufferIndex = -1;
public enum FrameStatus {
INVALID,
READY,
USING
}
public class Frame {
public FrameStatus mStatus;
public int mWidth;
public int mHeight;
public int mBufferSize;
public byte[] mImage;
public Frame(int width, int height) {
this.mWidth = width;
this.mHeight = height;
this.mBufferSize = mWidth * mHeight * 3 / 2; // Assuming YUV420 format
this.mImage = new byte[mBufferSize];
this.mStatus = FrameStatus.INVALID; // Initial status is INVALID
}
}
public FrameQueue(int bufferSize, int width, int height) {
this.mQueueBufferSize = bufferSize;
this.mQueueBuffer = new Frame[bufferSize];
for (int i = 0; i < bufferSize; ++i) {
this.mQueueBuffer[i] = new Frame(width, height);
}
}
// Helper method to get next index in a circular manner
private int getNextIndex(int currentIndex) {
return (currentIndex + 1) % mQueueBufferSize;
}
// Get a free frame for use.
public synchronized Frame getFreeFrame() {
int index = (mCurrentFreeBufferIndex + 1) % mQueueBufferSize;
for (int i = 0; i < mQueueBufferSize; ++i) {
if (mQueueBuffer[index].mStatus != FrameStatus.USING) {
break; // Found a free frame.
}
index = getNextIndex(index); // Move to next frame.
}
if (mQueueBuffer[index].mStatus != FrameStatus.USING) {
mCurrentFreeBufferIndex = index;
mQueueBuffer[index].mStatus = FrameStatus.INVALID; // Set the status before returning.
return mQueueBuffer[index];
}
return null; // No free frames available.
}
// Get a ready frame for processing.
public synchronized Frame pop() {
int index = getNextIndex(mCurrentUsingBufferIndex);
for (int i = 0; i < mQueueBufferSize; ++i) {
if (mQueueBuffer[index].mStatus == FrameStatus.READY) {
break; // Found a ready frame.
}
index = getNextIndex(index); // Move to next frame.
}
if ((index != mCurrentUsingBufferIndex)) {
if (mQueueBuffer[index].mStatus == FrameStatus.READY) {
mCurrentUsingBufferIndex = index;
mQueueBuffer[index].mStatus = FrameStatus.USING;
return mQueueBuffer[index];
}
}
return null; // No ready frames available.
}
// Mark the given frame as ready for use.
public synchronized void push(Frame buffer) {
buffer.mStatus = FrameStatus.READY;
}
// Clear all frames and reset their status.
public synchronized void clear() {
for (Frame frame : mQueueBuffer) {
releaseFrame(frame);
}
}
// Destroy the queue and release resources.
public void destroy() {
clear();
for (int i=0; i<mQueueBuffer.length;i++) {
if(mQueueBufffer[i]!=null){
Arrays.fill(mQeueBufffer[i],(byte)(0));
}
}
}
;
}
优化点解释:
- 枚举类型: 使用
enum
来定义帧状态,增加了代码的可读性。 - 循环逻辑封装: 将获取下一个索引的方法提取出来,使得循环逻辑更加清晰。
- 同步方法合理化: 确保对共享数据结构的访问是在合适的位置进行同步,以避免竞争条件。
- 资源释放增强: 在销毁缓冲区的时候清空帧内容(如果需要),并且提供了一个
clear()
方法以便于清空帧而不是单纯标记为无效。
内容由零声教学AI助手提供,问题来源于学员提问