public class DefaultExecutorRunnableListenerHelper extends RunnableListenerHelperThis class ensures that listener execution will never happen on the thread that invokes
RunnableListenerHelper.callListeners(). It does this in a different way from how the
AsyncCallRunnableListenerHelperdoes it. In this implementation the iteration of the listeners still occurs on the thread executing the
RunnableListenerHelper.callListeners(), but as listeners are added, it is ensured that they are provided an executor to execute on (so listener execution will actually happen on the executor). If a listener is provided with an executor, that provided Executor will NOT be overridden, and instead it will be used for the listeners execution.
Internally this class uses the
KeyDistributedExecutor, using the listener as the execution key, to ensure that any single listener will NEVER execute concurrently with itself.
In general, this implementation is most efficient when there are few listeners, but the listeners are high complexity, or take a long time to execute. If you have few listeners AND they execute quickly, the normal
RunnableListenerHelperis likely a better choice. If you have MANY listeners, but they execute very quickly,
AsyncCallRunnableListenerHelperis possibly a better choice.
AsyncCallRunnableListenerHelper, even if the executor provided here is multi-threaded, order of listener call's are preserved. So there is no need to provide a single threaded executor into this class.
All Methods Instance Methods Concrete Methods Modifier and Type Method Description
addListener(java.lang.Runnable listener, java.util.concurrent.Executor executor)Adds a listener to be called.
Methods inherited from class org.threadly.concurrent.event.RunnableListenerHelper
addListener, addListener, callListeners, clearListeners, getSubscribedListeners, registeredListenerCount, removeListener
public DefaultExecutorRunnableListenerHelper(boolean callListenersOnce, java.util.concurrent.Executor executor)Constructs a new
DefaultExecutorRunnableListenerHelper. If any listeners are not provided an executor, they will execute on the provided executor.
trueif listeners should only be called once
Executorto execute listeners which were not provided one by default
public void addListener(java.lang.Runnable listener, java.util.concurrent.Executor executor)Description copied from class:
RunnableListenerHelperAdds a listener to be called. If the
RunnableListenerHelperwas constructed with
true(listeners can only be called once) then this listener will be called immediately. If the executor is null it will be called either on this thread or the thread calling
RunnableListenerHelper.callListeners()(depending on the previous condition).
Executoris provided, and that Executor is NOT single threaded, the listener may be called concurrently. You can ensure this wont happen by using the
KeyDistributedExecutorto get an executor from a single key, or by using the
ExecutorLimiterwith a limit of one, or an instance of the