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;
 	}