title: Android LinkedBlockingQueue take clearing list
body: <p>in my android application I have HashMap of LinkedBlockingQueue:</p>
  
  <pre><code>private ConcurrentHashMap&lt;Integer, LinkedBlockingQueue&lt;short[]&gt;&gt; mBuffer = new ConcurrentHashMap&lt;Integer, LinkedBlockingQueue&lt;short[]&gt;&gt;(8,0.9f,1);
  </code></pre>
  
  <p>There is separate thread producing data for every key. Data is added this way:</p>
  
  <pre><code>public void addFrameCopy(Integer sampleId, short[] frame) {
      LinkedBlockingQueue&lt;short[]&gt; value;
  
      if (!mBuffer.containsKey(id)) {
          value= new LinkedBlockingQueue&lt;short[]&gt;();
          mBuffer.put(id, value);
      } else {
          value = mBuffer.get(sampleId);
      }
  
      Log.d("IN "+id,inCounter+" "+getShortArraySum(frame)+"");
  
      inCounter++;
  
      value.add(Arrays.copyOf(frame,frame.length));
  }
  </code></pre>
  
  <p>And one consumer thread for all keys. Consumption works this way:</p>
  
  <pre><code>public List&lt;Pair&lt;ControlFrame, short[]&gt;&gt; getCombinedFramesBatchSkipWhenNeeded
          (List&lt;Pair&lt;Integer, ControlFrame&gt;&gt; controlFrames,
           List&lt;Pair&lt;ControlFrame, short[]&gt;&gt; out) {
  
      Set&lt;Integer&gt; nonUsedKeys = mBuffer.keySet();
  
      LinkedBlockingQueue&lt;short[]&gt; list;
  
      short[] takenDataFrame;
      for (Pair&lt;Integer, ControlFrame&gt; controlPair : controlFrames) {
          if (shouldSatisfyControlFrame(controlPair.second)) {
  
              list=mBuffer.get(controlPair.first);
              try {
                  takenDataFrame = list.take();
              } catch (InterruptedException e) {
                  e.printStackTrace();
                  continue;
              }
  
              Pair&lt;ControlFrame, short[]&gt; combinedFrame = new Pair&lt;ControlFrame, short[]&gt;(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;
  }
  </code></pre>
  
  <p>Method attemptToSkipFrames is never called.
  I am running tests for one producing thread. Here are logs I am getting:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>Looks like take no. 2 is clearing list, causing take no. 3 to get value inserted as no. 5. 
  How can I prevent losing items?</p>
  
  <p><strong>Simplified</strong></p>
  
  <p>Methods used to insert and take data without hashmap code.</p>
  
  <pre><code>public void addFrameCopy(Integer sampleId, short[] frame) {
      LinkedBlockingQueue&lt;short[]&gt; value=getQueue(sampleId);
  
      Log.d("IN "+id,inCounter+" "+getShortArraySum(frame)+"");
  
      inCounter++;
  
      value.add(Arrays.copyOf(frame,frame.length));
  }
  
  public List&lt;Pair&lt;ControlFrame, short[]&gt;&gt; getCombinedFramesBatchSkipWhenNeeded
          (List&lt;Pair&lt;Integer, ControlFrame&gt;&gt; controlFrames,
           List&lt;Pair&lt;ControlFrame, short[]&gt;&gt; out) {
  
      LinkedBlockingQueue&lt;short[]&gt; list;
      short[] takenDataFrame;
  
      for (Pair&lt;Integer, ControlFrame&gt; controlPair : controlFrames) {
              list=getQueue(controlPair.first);
              try {
                  takenDataFrame = list.take();
              } catch (InterruptedException e) {
                  e.printStackTrace();
                  continue;
              }
  
              Pair&lt;ControlFrame, short[]&gt; combinedFrame = new Pair&lt;ControlFrame, short[]&gt;(controlPair.second, takenDataFrame);
  
              Log.d("OUT "+controlPair.first,outCounter+" "+getShortArraySum(takenDataFrame)+"");
  
              outCounter++;
  
              out.add(combinedFrame);
  
      }
      return out;
  }
  </code></pre>