Browse Source

Do not lock on settings keyset if keys initialized (#52435)

Every time a setting#exist call is made we lock on the keyset to ensure
that it has been initialized. This a heavyweight operation that only
should be done once. This commit moves to a volatile read instead to
prevent unnecessary locking.
Tim Brooks 5 years ago
parent
commit
b97cc0c987
1 changed files with 11 additions and 8 deletions
  1. 11 8
      server/src/main/java/org/elasticsearch/common/settings/Settings.java

+ 11 - 8
server/src/main/java/org/elasticsearch/common/settings/Settings.java

@@ -690,14 +690,17 @@ public final class Settings implements ToXContentFragment {
 
     /** Returns the fully qualified setting names contained in this settings object. */
     public Set<String> keySet() {
-        synchronized (keys) {
-            if (keys.get() == null) {
-                if (secureSettings == null) {
-                    keys.set(settings.keySet());
-                } else {
-                    Stream<String> stream = Stream.concat(settings.keySet().stream(), secureSettings.getSettingNames().stream());
-                    // uniquify, since for legacy reasons the same setting name may exist in both
-                    keys.set(Collections.unmodifiableSet(stream.collect(Collectors.toSet())));
+        if (keys.get() == null) {
+            synchronized (keys) {
+                // Check that the keys are still null now that we have acquired the lock
+                if (keys.get() == null) {
+                    if (secureSettings == null) {
+                        keys.set(settings.keySet());
+                    } else {
+                        Stream<String> stream = Stream.concat(settings.keySet().stream(), secureSettings.getSettingNames().stream());
+                        // uniquify, since for legacy reasons the same setting name may exist in both
+                        keys.set(Collections.unmodifiableSet(stream.collect(Collectors.toSet())));
+                    }
                 }
             }
         }