Index: src/main/java/org/apache/http/impl/conn/IdleConnectionHandler.java =================================================================== --- src/main/java/org/apache/http/impl/conn/IdleConnectionHandler.java (revision 899417) +++ src/main/java/org/apache/http/impl/conn/IdleConnectionHandler.java (working copy) @@ -26,70 +26,69 @@ package org.apache.http.impl.conn; import java.io.IOException; -import java.util.HashMap; -import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.concurrent.TimeUnit; -import org.apache.http.annotation.NotThreadSafe; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpConnection; +import org.apache.http.annotation.NotThreadSafe; // Currently only used by AbstractConnPool /** * A helper class for connection managers to track idle connections. - * + * *

This class is not synchronized.

- * + * * @see org.apache.http.conn.ClientConnectionManager#closeIdleConnections - * + * * @since 4.0 */ @NotThreadSafe public class IdleConnectionHandler { private final Log log = LogFactory.getLog(getClass()); - + /** Holds connections and the time they were added. */ private final Map connectionToTimes; - + public IdleConnectionHandler() { super(); - connectionToTimes = new HashMap(); + connectionToTimes = new LinkedHashMap(); } - + /** - * Registers the given connection with this handler. The connection will be held until + * Registers the given connection with this handler. The connection will be held until * {@link #remove} or {@link #closeIdleConnections} is called. - * + * * @param connection the connection to add - * + * * @see #remove */ - public void add(HttpConnection connection, long validDuration, TimeUnit unit) { - - long timeAdded = System.currentTimeMillis(); - + public void add(final HttpConnection connection, final long validDuration, final TimeUnit unit) { + + final long timeAdded = System.currentTimeMillis(); + if (log.isDebugEnabled()) { log.debug("Adding connection at: " + timeAdded); } - + connectionToTimes.put(connection, new TimeValues(timeAdded, validDuration, unit)); } - + /** * Removes the given connection from the list of connections to be closed when idle. * This will return true if the connection is still valid, and false * if the connection should be considered expired and not used. - * + * * @param connection * @return True if the connection is still valid. */ - public boolean remove(HttpConnection connection) { - TimeValues times = connectionToTimes.remove(connection); + public boolean remove(final HttpConnection connection) { + final TimeValues times = connectionToTimes.remove(connection); if(times == null) { log.warn("Removing a connection that never existed!"); return true; @@ -104,65 +103,63 @@ public void removeAll() { this.connectionToTimes.clear(); } - + /** * Closes connections that have been idle for at least the given amount of time. - * + * * @param idleTime the minimum idle time, in milliseconds, for connections to be closed */ - public void closeIdleConnections(long idleTime) { - + public void closeIdleConnections(final long idleTime) { + // the latest time for which connections will be closed - long idleTimeout = System.currentTimeMillis() - idleTime; + final long idleTimeout = System.currentTimeMillis() - idleTime; if (log.isDebugEnabled()) { log.debug("Checking for connections, idle timeout: " + idleTimeout); } - Iterator connectionIter = connectionToTimes.keySet().iterator(); - - while (connectionIter.hasNext()) { - HttpConnection conn = connectionIter.next(); - TimeValues times = connectionToTimes.get(conn); - long connectionTime = times.timeAdded; + + for (final Entry entry : connectionToTimes.entrySet()) + { + final HttpConnection conn = entry.getKey(); + final TimeValues times = entry.getValue(); + final long connectionTime = times.timeAdded; if (connectionTime <= idleTimeout) { if (log.isDebugEnabled()) { log.debug("Closing idle connection, connection time: " + connectionTime); } try { conn.close(); - } catch (IOException ex) { + } catch (final IOException ex) { log.debug("I/O error closing connection", ex); } } } } - + public void closeExpiredConnections() { - long now = System.currentTimeMillis(); + final long now = System.currentTimeMillis(); if (log.isDebugEnabled()) { log.debug("Checking for expired connections, now: " + now); } - - Iterator connectionIter = - connectionToTimes.keySet().iterator(); - - while (connectionIter.hasNext()) { - HttpConnection conn = connectionIter.next(); - TimeValues times = connectionToTimes.get(conn); + + for (final Entry entry : connectionToTimes.entrySet()) + { + final HttpConnection conn = entry.getKey(); + final TimeValues times = entry.getValue(); if(times.timeExpires <= now) { if (log.isDebugEnabled()) { log.debug("Closing connection, expired @: " + times.timeExpires); } try { conn.close(); - } catch (IOException ex) { + } catch (final IOException ex) { log.debug("I/O error closing connection", ex); } } - } + } } - + private static class TimeValues { private final long timeAdded; private final long timeExpires; @@ -172,7 +169,7 @@ * @param validDuration The duration this connection is valid for * @param validUnit The unit of time the duration is specified in. */ - TimeValues(long now, long validDuration, TimeUnit validUnit) { + TimeValues(final long now, final long validDuration, final TimeUnit validUnit) { this.timeAdded = now; if(validDuration > 0) { this.timeExpires = now + validUnit.toMillis(validDuration);