From 7fcd997b3984aa654d9856cf114e2e4b0d3c7fa6 Mon Sep 17 00:00:00 2001 From: Tim Brooks Date: Tue, 18 Feb 2020 08:08:39 -0700 Subject: [PATCH] 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. --- .../common/settings/Settings.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/settings/Settings.java b/server/src/main/java/org/elasticsearch/common/settings/Settings.java index dcde1789152..42fdbb6a7c1 100644 --- a/server/src/main/java/org/elasticsearch/common/settings/Settings.java +++ b/server/src/main/java/org/elasticsearch/common/settings/Settings.java @@ -716,14 +716,17 @@ public final class Settings implements ToXContentFragment { /** Returns the fully qualified setting names contained in this settings object. */ public Set keySet() { - synchronized (keys) { - if (keys.get() == null) { - if (secureSettings == null) { - keys.set(settings.keySet()); - } else { - Stream 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 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()))); + } } } }