diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/HBaseClient.java hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/HBaseClient.java index 33786b7..981ed93 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/HBaseClient.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/HBaseClient.java @@ -1409,11 +1409,15 @@ public class HBaseClient { * refs for keys in HashMap properly. For now its ok. */ ConnectionId remoteId = new ConnectionId(addr, protocol, ticket, rpcTimeout); - synchronized (connections) { - connection = connections.get(remoteId); - if (connection == null) { - connection = createConnection(remoteId); - connections.put(remoteId, connection); + connection = connections.get(remoteId); + if (connection == null) { + synchronized (connections) { + // Recheck since another thread might have added a connection. + connection = connections.get(remoteId); + if (connection == null) { + connection = createConnection(remoteId); + connections.put(remoteId, connection); + } } } connection.addCall(call); diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/util/PoolMap.java hbase-server/src/main/java/org/apache/hadoop/hbase/util/PoolMap.java index 364be66..ada265b 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/util/PoolMap.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/util/PoolMap.java @@ -28,6 +28,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicInteger; @@ -59,15 +60,18 @@ public class PoolMap implements Map { private int poolMaxSize; - private Map> pools = new ConcurrentHashMap>(); + private ConcurrentMap> pools = new ConcurrentHashMap>(); + private volatile Pool singletonPool; public PoolMap(PoolType poolType) { this.poolType = poolType; + this.singletonPool = createPool(); } public PoolMap(PoolType poolType, int poolMaxSize) { this.poolType = poolType; this.poolMaxSize = poolMaxSize; + this.singletonPool = createPool(); } @Override @@ -78,11 +82,13 @@ public class PoolMap implements Map { @Override public V put(K key, V value) { - Pool pool = pools.get(key); - if (pool == null) { - pools.put(key, pool = createPool()); + Pool returnPool = pools.putIfAbsent(key, singletonPool); + if (returnPool != null) { + return returnPool.put(value); } - return pool != null ? pool.put(value) : null; + V returnValue = singletonPool.put(value); + singletonPool = createPool(); + return returnValue; } @SuppressWarnings("unchecked")