title: Mulitple threads are trying to write with milliseconds as key, but instead of one key many keys are created in ConcurrentHashMap
body: <pre><code>ConcurrentHashMap&lt;Long, CopyOnWriteArrayList&lt;Observation&gt;
  mostRecentObservationDB = new ConcurrentHashMap&lt;Long,
      CopyOnWriteArrayList&lt;Observation&gt;(524288, 0.75f, 32);
  </code></pre>
  
  <p>This is my map. I am trying to read and write with multiple threads at the same time, but somehow it always creates multiple keys.</p>
  
  <pre><code>long timeInMilliseconds = System.currentTimeMillis();
  
  if (/* the last key older than 10 seconds comparing to the new key*/) {
      CopyOnWriteArrayList&lt;Observation&gt; initializingObservation = new CopyOnWriteArrayList&lt;&gt;();
      initializingObservation.add(obs);
  
      mostRecentObservationDB.putIfAbsent(timeInMilliseconds, initializingObservation);
  } else {
    // Update
  }
  </code></pre>
  
  <p>Seperate Thread, which filters this hash map by deleting the keys which are older than 10 seconds. </p>
  
  <pre><code>while (true) {
      try {
          Thread.sleep(4000);
          if(/*Time (key) older than 10 seconds*/) {
              mostRecentObservationDB.remove(key);
          }
  
      } catch (Exception e) {
  
      }
  }
  </code></pre>
  
  <p>The problem is that after removing the key, it creates multiple keys while initializing. This are my logs.</p>
  
  <pre><code>key -&gt; 1501779153776, value
  key -&gt; 1501779153826, value
  key -&gt; 1501779153876, value
  key -&gt; 1501779153896, value
  </code></pre>
  
  <p>I want them to be stored as one key while removing operation. This is how it should be stored.</p>
  
  <pre><code>key -&gt; 1501779153776, value
  </code></pre>
  
  <p>However, when I read from it and then remove all entries by <code>remove()</code> method, I want that no other thread writes to the map while I’m in the process of reading the map contents and then removing them.</p>
  
  <hr>
  
  <p>This is the code which is behaving odd:</p>
  
  <pre><code>public static void main(String[] args) {
      ConcurrentHashMap&lt;Long, String&gt; tenSecondBucket =
          new ConcurrentHashMap&lt;Long, String&gt;();
  
      Thread writingThread = new Thread(new Runnable() {
          @Override
          public void run() {
              while (true) {
                  try {
                      Thread.sleep(1);
  
                      if(tenSecondBucket.size() &gt; 0) {
                          // getting last key
                          long lastKey = 0;
                          for (long keyValue : tenSecondBucket.keySet()) {
                              lastKey = keyValue;
                          }
  
                          if(System.currentTimeMillis() - lastKey &gt; 10000) {
                              tenSecondBucket.put(System.currentTimeMillis(), "secondEntry");
                          } else {
                              tenSecondBucket.put(lastKey, "updatedEntry");
                          }
                      } else {
                          tenSecondBucket.put(System.currentTimeMillis(), "newEntry");
                      }
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }
      });
  
      writingThread.start();
  
      Thread removingThread = new Thread(new Runnable() {
          @Override
          public void run() {
              while (true) {
                  try {
                      Thread.sleep(4000);
  
                      if(tenSecondBucket.size() &gt; 0) {
                          tenSecondBucket.keySet().stream().forEach(key -&gt; {
                              if(System.currentTimeMillis() - key &gt; 10000) {
                                  tenSecondBucket.remove(key);
                              }
                          });
                      }
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }
      });
  
      removingThread.start();
  
      Thread readingThread = new Thread(new Runnable() {
          @Override
          public void run() {
              while (true) {
                  try {
                      Thread.sleep(4000);
  
                      if(tenSecondBucket.size() &gt; 0) {
                          tenSecondBucket.keySet().stream().forEach(key -&gt; {
                              System.out.println("testing key which is timestamp " + key);
                          });
                      }
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }
      });
  
      readingThread.start();
  }
  </code></pre>