在我的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;
}
方法尝试永远不会调用ToskipFrames。 我正在为一个生产线程运行测试。这是我得到的日志:
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将值插入为no。 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;
}
答案 0 :(得分:1)
在按照Ralf的建议/要求玩简化的单一版本时,我设法找到了bug。事实证明问题是由删除hashmap键的manul,而不是队列中的一些concurency问题引起的。通过更改
修复了它Set<Integer> nonUsedKeys = mBuffer.keySet();
到
Set<Integer> nonUsedKeys = new LinkedHashSet<Integer>(mBuffer.keySet());