Index: src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java =================================================================== --- src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java (revision 502650) +++ src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java (working copy) @@ -113,12 +113,20 @@ synchronized (REFERENCE_TO_CONNECTION_SOURCE) { // shutdown all connection managers synchronized (ALL_CONNECTION_MANAGERS) { - Iterator connIter = ALL_CONNECTION_MANAGERS.keySet().iterator(); - while (connIter.hasNext()) { - MultiThreadedHttpConnectionManager connManager = - (MultiThreadedHttpConnectionManager) connIter.next(); - connIter.remove(); - connManager.shutdown(); + // Don't use an iterator here. Iterators on WeakHashMap can + // get ConcurrentModificationException on garbage collection. + MultiThreadedHttpConnectionManager[] + connManagers = (MultiThreadedHttpConnectionManager[]) + ALL_CONNECTION_MANAGERS.keySet().toArray( + new MultiThreadedHttpConnectionManager + [ALL_CONNECTION_MANAGERS.size()] + ); + + // The map may shrink after size() is called, or some entry + // may get GCed while the array is built, so expect null. + for (int i=0; iThe connection manager can no longer be used once shutdown. + *

The connection manager can no longer be used once shut down. * *

Calling this method more than once will have no effect. */ @@ -1033,7 +1041,7 @@ */ private static class ReferenceQueueThread extends Thread { - private boolean shutdown = false; + private volatile boolean shutdown = false; /** * Create an instance and make this a daemon thread. @@ -1045,6 +1053,7 @@ public void shutdown() { this.shutdown = true; + this.interrupt(); } /** @@ -1078,10 +1087,8 @@ public void run() { while (!shutdown) { try { - // remove the next reference and process it, a timeout - // is used so that the thread does not block indefinitely - // and therefore keep the thread from shutting down - Reference ref = REFERENCE_QUEUE.remove(1000); + // remove the next reference and process it + Reference ref = REFERENCE_QUEUE.remove(); if (ref != null) { handleReference(ref); }