From 0fdc754af8758f62a822c6c5aaa23baa40cf834f Mon Sep 17 00:00:00 2001 From: David Turner Date: Fri, 23 Dec 2022 14:59:38 +0000 Subject: [PATCH] Release delegate ref in RunOnce (#92507) Like #92452 but for `RunOnce`. --- .../common/util/concurrent/RunOnce.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/util/concurrent/RunOnce.java b/server/src/main/java/org/elasticsearch/common/util/concurrent/RunOnce.java index 0b9334a03c448..23d62307cb8cd 100644 --- a/server/src/main/java/org/elasticsearch/common/util/concurrent/RunOnce.java +++ b/server/src/main/java/org/elasticsearch/common/util/concurrent/RunOnce.java @@ -8,25 +8,24 @@ package org.elasticsearch.common.util.concurrent; import java.util.Objects; -import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; /** - * Runnable that can only be run one time. + * Runnable that prevents running its delegate more than once. */ public class RunOnce implements Runnable { - private final Runnable delegate; - private final AtomicBoolean hasRun; + private final AtomicReference delegateRef; public RunOnce(final Runnable delegate) { - this.delegate = Objects.requireNonNull(delegate); - this.hasRun = new AtomicBoolean(false); + delegateRef = new AtomicReference<>(Objects.requireNonNull(delegate)); } @Override public void run() { - if (hasRun.compareAndSet(false, true)) { - delegate.run(); + var acquired = delegateRef.getAndSet(null); + if (acquired != null) { + acquired.run(); } } @@ -34,6 +33,6 @@ public void run() { * {@code true} if the {@link RunOnce} has been executed once. */ public boolean hasRun() { - return hasRun.get(); + return delegateRef.get() == null; } }