java - Android LinkedBlockingQueue 取清空列表

标签 java android multithreading concurrency queue

在我的 android 应用程序中,我有 LinkedBlockingQueue 的 HashMap:

private ConcurrentHashMap<Integer, LinkedBlockingQueue<short[]>> mBuffer = new ConcurrentHashMap<Integer, LinkedBlockingQueue<short[]>>(8,0.9f,1);

每个键都有单独的线程生成数据。数据以这种方式添加:

public void addFrameCopy(Integer sampleId, short[] frame) {
    LinkedBlockingQueue<short[]> value;

    if (!mBuffer.containsKey(id)) {
        value= new LinkedBlockingQueue<short[]>();
        mBuffer.put(id, value);
    } else {
        value = mBuffer.get(sampleId);
    }

    Log.d("IN "+id,inCounter+" "+getShortArraySum(frame)+"");

    inCounter++;

    value.add(Arrays.copyOf(frame,frame.length));
}

所有键都有一个消费者线程。消费是这样运作的:

public List<Pair<ControlFrame, short[]>> getCombinedFramesBatchSkipWhenNeeded
        (List<Pair<Integer, ControlFrame>> controlFrames,
         List<Pair<ControlFrame, short[]>> out) {

    Set<Integer> nonUsedKeys = mBuffer.keySet();

    LinkedBlockingQueue<short[]> list;

    short[] takenDataFrame;
    for (Pair<Integer, ControlFrame> controlPair : controlFrames) {
        if (shouldSatisfyControlFrame(controlPair.second)) {

            list=mBuffer.get(controlPair.first);
            try {
                takenDataFrame = list.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
                continue;
            }

            Pair<ControlFrame, short[]> combinedFrame = new Pair<ControlFrame, short[]>(controlPair.second, takenDataFrame);

            Log.d("OUT "+controlPair.first,outCounter+" "+getShortArraySum(takenDataFrame)+"");

            outCounter++;

            out.add(combinedFrame);

            nonUsedKeys.remove(controlPair.first);
        } else {
            attemptToSkipFrames(controlPair);
        }
    }

    for (Integer key : nonUsedKeys) {
        Log.d("OUT "+key,"Skip");
            list=mBuffer.get(key);
        if(!list.isEmpty())
            list.remove(0);
    }

    return out;
}

从未调用方法 attemptToSkipFrames。 我正在为一个生产线程运行测试。这是我得到的日志:

IN  9﹕ 0 0
OUT 9﹕ 0 0
IN  9﹕ 1 26494
OUT 9﹕ 1 26494
IN  9﹕ 2 203342
IN  9﹕ 3 -427941
IN  9﹕ 4 31709
OUT 9﹕ 2 203342
IN  9﹕ 5 457126
OUT 9﹕ 3 457126

看起来没有。 2是清除列表,导致没有。 3 获取插入的值。 5. 如何防止丢失元素?

简化

用于在没有 hashmap 代码的情况下插入和获取数据的方法。

public void addFrameCopy(Integer sampleId, short[] frame) {
    LinkedBlockingQueue<short[]> value=getQueue(sampleId);

    Log.d("IN "+id,inCounter+" "+getShortArraySum(frame)+"");

    inCounter++;

    value.add(Arrays.copyOf(frame,frame.length));
}

public List<Pair<ControlFrame, short[]>> getCombinedFramesBatchSkipWhenNeeded
        (List<Pair<Integer, ControlFrame>> controlFrames,
         List<Pair<ControlFrame, short[]>> out) {

    LinkedBlockingQueue<short[]> list;
    short[] takenDataFrame;

    for (Pair<Integer, ControlFrame> controlPair : controlFrames) {
            list=getQueue(controlPair.first);
            try {
                takenDataFrame = list.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
                continue;
            }

            Pair<ControlFrame, short[]> combinedFrame = new Pair<ControlFrame, short[]>(controlPair.second, takenDataFrame);

            Log.d("OUT "+controlPair.first,outCounter+" "+getShortArraySum(takenDataFrame)+"");

            outCounter++;

            out.add(combinedFrame);

    }
    return out;
}

最佳答案

在按照 Ralf 的建议/要求玩它的简化单类版本时,我设法找到了错误。事实证明问题是由手动删除 HashMap 键引起的,而不是队列中的某些并发问题。通过更改修复它

Set<Integer> nonUsedKeys = mBuffer.keySet();

Set<Integer> nonUsedKeys = new LinkedHashSet<Integer>(mBuffer.keySet());

关于java - Android LinkedBlockingQueue 取清空列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26799266/

相关文章:

单复数相同的项目集合的 Java 命名约定

java - 基本 Java 问题 : throwing an exception to a later catch clause?

java - 如何用两个独立的线程进行等待和通知?

Java:将unix时间(长)舍入到该月的第一天

android - 如何更改应用程序 ID 但保持相同的资源 ID?

asp.net - 了解ASP.Net实例和线程

使用 Robolectric 进行 Android 单元测试会抛出错误 AndroidManifest.xml 未找到或不是文件

java - 选择抽屉项目后滚动到新选项卡

由 C# 锁定

python - Python 中的多线程爬虫真的可以加快速度吗?