title: Proper way to remove elements from synchronized lists
body: <p>I have a client-server style design. What I have done is create a class called <code>RequestController</code> that controls and monitors all server requests made as a threaded object.  </p>
  
  <p>These request threads are tracked in a synchronized <code>Map</code> (created with <code>Collections.synchronizedMap(new HashMap&lt;Long, RequestThread&gt;())</code>). Every half second each request thread is checked, if it is still alive it sends a progress message to its interested listener object (an attribute of the request thread) if it has completed or failed it notifies the interested listener and removes itself from the synchronized <code>Map</code> when its <code>run()</code> method completes.</p>
  
  <p>The <code>RequestThread</code> object that I use to track each request is a protected inner class of the <code>RequestController</code> object that is monitoring all the requests.  So it has access to the map that contains it.</p>
  
  <p>It is here that I am having problems. I get concurrent modification exceptions when the "dead thread" is removed from the map. All my access to the map is synchronized so I don't understand how I can get an exception.</p>
  
  <p>Here is the control loop code:</p>
  
  <pre><code>this.reqTimer = new Timer("Request Timer", true);
  TimerTask reqTask = new TimerTask()
  {
      @Override
      public void run()
      {
          synchronized(reqList)
          {
              for(RequestThread rt : reqList.values())
                  rt.updateProgress();
          }
      }
  };
  this.reqTimer.scheduleAtFixedRate(reqTask, 500L, 500L);
  </code></pre>
  
  <p>At the very end of the <code>RequestThread.run()</code> method there is call to the <code>RequestController</code> method to remove itself from the map like so:</p>
  
  <pre><code>   public void removeRequest(long id)
     {
         synchronized(this.reqList)
         {
             this.reqList.remove(id);
         }
     }
  </code></pre>
  
  <p>It appears that if a <code>RequestThread.run()</code> completes while the <code>TimerTask.run()</code> method is looping through the map of requests to invoke the <code>updateProgress()</code> method the remove is not blocked but is allowed to alter the map and cause my exception. How can two different threads get a lock on the same object at the same time?  Shouldn't the remove be blocked because it originates in a different thread until the update is complete?</p>