code: private Connection getConnection(InetSocketAddress addr,
                                     Class<?> protocol,
                                     UserGroupInformation ticket,
                                     int rpcTimeout,
                                     Call call)
                                     throws IOException {
      if (!running.get()) {
        // the client is stopped
        throw new IOException("The client is stopped");
      }
      Connection connection;
      /* we could avoid this allocation for each RPC by having a  
       * connectionsId object and with set() method. We need to manage the
       * refs for keys in HashMap properly. For now its ok.
       */
      ConnectionId remoteId = new ConnectionId(
  		addr, protocol, ticket, rpcTimeout);
      do {
        synchronized (connections) {
          connection = connections.get(remoteId);
          if (connection == null) {
            connection = new Connection(remoteId);
            connections.put(remoteId, connection);
          }
        }
      } while (!connection.addCall(call));
      
      //we don't invoke the method below inside "synchronized (connections)"
      //block above. The reason for that is if the server happens to be slow,
      //it will take longer to establish a connection and that will slow the
      //entire system down.
      boolean success = false;
      try {
        connection.setupIOstreams();
        success = true;
      } finally {
        if (!success) {
          // We need to make sure connection is removed from connections object if
          // there is any unhandled exception (like OOM). In this case, unlikely
          // there is response thread started which can clear the connection
          // eventually.
          try {
            if (connection.closeException == null) {
              connection.markClosed(new IOException(
                  "Unexpected error when setup IO Stream"));
            }
          } finally {
            connection.close(true);
          }
        }
      }
      return connection;
    }
docs: Get a connection from the pool, or create a new one and add it to the
  pool.  Connections to a given host/port are reused.