java.lang.Object
org.elasticsearch.action.support.RefCountingRunnable
- All Implemented Interfaces:
Closeable
,AutoCloseable
,Releasable
A mechanism to trigger an action on the completion of some (dynamic) collection of other actions. Basic usage is as follows:
try (var refs = new RefCountingRunnable(finalRunnable)) { for (var item : collection) { runAsyncAction(item, refs.acquire()); // releases the acquired ref on completion } }The delegate action is completed when execution leaves the try-with-resources block and every acquired reference is released. Unlike a
CountDown
there is no need to declare the number of subsidiary actions up front (refs can be acquired dynamically as needed) nor
does the caller need to check for completion each time a reference is released. Moreover even outside the try-with-resources block you
can continue to acquire additional references, even in a separate thread, as long as there's at least one reference outstanding:
try (var refs = new RefCountingRunnable(finalRunnable)) { for (var item : collection) { if (condition(item)) { runAsyncAction(item, refs.acquire()); } } if (flag) { runOneOffAsyncAction(refs.acquire()); return; } for (var item : otherCollection) { var itemRef = refs.acquire(); // delays completion while the background action is pending executorService.execute(() -> { try (var ignored = itemRef) { if (condition(item)) { runOtherAsyncAction(item, refs.acquire()); } } }); } }In particular (and also unlike a
CountDown
) this works even if you don't acquire any extra refs at all: in that case, the
delegate action executes at the end of the try-with-resources block.-
Constructor Summary
ConstructorDescriptionRefCountingRunnable
(Runnable delegate) Construct aRefCountingRunnable
which executesdelegate
when all refs are released. -
Method Summary
Modifier and TypeMethodDescriptionacquire()
Acquire a reference to this object and return an action which releases it.Acquire a reference to this object and return a listener which releases it when notified.void
close()
Release the original reference to this object, which executes the delegateRunnable
if there are no other references.toString()
-
Constructor Details
-
RefCountingRunnable
Construct aRefCountingRunnable
which executesdelegate
when all refs are released.- Parameters:
delegate
- The action to execute when all refs are released. This action must not throw any exception.
-
-
Method Details
-
acquire
Acquire a reference to this object and return an action which releases it. The delegateRunnable
is called when all its references have been released. It is invalid to call this method once all references are released. Doing so will trip an assertion if assertions are enabled, and will throw anIllegalStateException
otherwise. It is also invalid to release the acquired resource more than once. Doing so will trip an assertion if assertions are enabled, but will be ignored otherwise. This deviates from the contract ofCloseable
. -
acquireListener
Acquire a reference to this object and return a listener which releases it when notified. The delegateRunnable
is called when all its references have been released. -
close
public void close()Release the original reference to this object, which executes the delegateRunnable
if there are no other references. It is invalid to call this method more than once. Doing so will trip an assertion if assertions are enabled, but will be ignored otherwise. This deviates from the contract ofCloseable
.- Specified by:
close
in interfaceAutoCloseable
- Specified by:
close
in interfaceCloseable
- Specified by:
close
in interfaceReleasable
-
toString
-