Proposition: Use ConcurrentHashMap to avoid locking when using the clientOracleCache. Review at http://gwt-code-reviews.appspot.com/1425803 git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10026 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/rpc/server/RpcServlet.java b/user/src/com/google/gwt/rpc/server/RpcServlet.java index e094187..f7c5c0d 100644 --- a/user/src/com/google/gwt/rpc/server/RpcServlet.java +++ b/user/src/com/google/gwt/rpc/server/RpcServlet.java
@@ -33,8 +33,8 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.UnknownHostException; -import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.zip.GZIPOutputStream; import javax.servlet.ServletException; @@ -53,7 +53,7 @@ protected static final String CLIENT_ORACLE_EXTENSION = ".gwt.rpc"; private static final boolean DUMP_PAYLOAD = Boolean.getBoolean("gwt.rpc.dumpPayload"); - private final Map<String, SoftReference<ClientOracle>> clientOracleCache = new HashMap<String, SoftReference<ClientOracle>>(); + private final Map<String, SoftReference<ClientOracle>> clientOracleCache = new ConcurrentHashMap<String, SoftReference<ClientOracle>>(); /** * The implementation of the service. @@ -98,6 +98,17 @@ ClientOracle toReturn; + // Fast path if the ClientOracle is already cached. + if (clientOracleCache.containsKey(permutationStrongName)) { + toReturn = clientOracleCache.get(permutationStrongName).get(); + if (toReturn != null) { + return toReturn; + } + } + + /* Synchronize to make sure expensive calls are executed only once. + Double checked locking idiom works here because of volatiles in + ConcurrentHashMap.*/ synchronized (clientOracleCache) { if (clientOracleCache.containsKey(permutationStrongName)) { toReturn = clientOracleCache.get(permutationStrongName).get();