WICKET-7002 Remove blocking code from Application#get/setMetaData
By replacing the datastructure for Application class's metaData field
with a ConcurrentHashMap we can remove the synchronization on the
application instance and speed up lookups of the metadata. For at least
one application this will remove 50% of all blocking calls.
diff --git a/wicket-core/src/main/java/org/apache/wicket/Application.java b/wicket-core/src/main/java/org/apache/wicket/Application.java
index 073a2b7..36d74d2 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Application.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Application.java
@@ -23,6 +23,7 @@
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import org.apache.wicket.application.ComponentInitializationListenerCollection;
import org.apache.wicket.application.ComponentInstantiationListenerCollection;
@@ -159,7 +160,7 @@
private final List<IInitializer> initializers = Generics.newArrayList();
/** Application level meta data. */
- private MetaDataEntry<?>[] metaData;
+ private ConcurrentHashMap<MetaDataKey<?>, Object> metaData = new ConcurrentHashMap<>();
/** Name of application subclass. */
private String name;
@@ -394,9 +395,10 @@
* @see MetaDataKey
*/
@Override
- public final synchronized <T> T getMetaData(final MetaDataKey<T> key)
+ @SuppressWarnings("unchecked")
+ public final <T> T getMetaData(final MetaDataKey<T> key)
{
- return key.get(metaData);
+ return (T)metaData.get(key);
}
/**
@@ -508,9 +510,9 @@
* @see MetaDataKey
*/
@Override
- public synchronized final <T> Application setMetaData(final MetaDataKey<T> key, final T object)
+ public final <T> Application setMetaData(final MetaDataKey<T> key, final T object)
{
- metaData = key.set(metaData, object);
+ metaData.put(key, object);
return this;
}