All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jtrim2.access.AbstractAccessToken Maven / Gradle / Ivy

package org.jtrim2.access;

import java.util.concurrent.TimeUnit;
import org.jtrim2.cancel.CancellationToken;
import org.jtrim2.event.EventListeners;
import org.jtrim2.event.ListenerRef;
import org.jtrim2.event.OneShotListenerManager;

/**
 * A convenient base class for {@link AccessToken} implementations.
 * 

* This class implements the {@code addTerminateListener} listener method but * subclasses need to call the {@code #notifyReleaseListeners()} method * after the {@code AccessToken} was released. This abstract class * provides a safe and robust handling of release listeners. The provided * implementation will guarantee that listeners will not be notified multiple * times and will be automatically unregistered after they have been notified * (allowing the listeners to be garbage collected, even if not unregistered * manually). *

* This class also adds a simple implementation for the * {@link #awaitRelease(CancellationToken) awaitRelease(CancellationToken)} * method which relies on the other {@code awaitRelease} method (the one with * the timeout argument). * * @param the type of the access ID (see * {@link AccessToken#getAccessID() getAccessID()}) */ public abstract class AbstractAccessToken implements AccessToken { private final OneShotListenerManager listeners; /** * Initializes the {@code AbstractAccessToken}. */ public AbstractAccessToken() { this.listeners = new OneShotListenerManager<>(); } /** * Notifies the currently registered release listeners. This method may * only be called if this {@code AccessToken} is already in the released * state (i.e.: {@link #isReleased() isReleased()} returns {@code true}. * Note that once a {@code TaskExecutorService} is in the released state it * must remain in the terminated state forever after. The * {@code AbstractAccessToken} actually relies on this property for * correctness. *

* If called after this token is already in released state, this method is * idempotent. */ protected final void notifyReleaseListeners() { if (!isReleased()) { throw new IllegalStateException( "May only be called in the terminated state."); } EventListeners.dispatchRunnable(listeners); } /** * {@inheritDoc } *

* Implementation note: Listeners added by this method will be * automatically unregistered after they have been notified. */ @Override public ListenerRef addReleaseListener(Runnable listener) { return listeners.registerOrNotifyListener(listener); } /** * {@inheritDoc } *

* Implementation note: This method simply repeatedly calls the * {@link #tryAwaitRelease(CancellationToken, long, TimeUnit) tryAwaitRelease(CancellationToken, long, TimeUnit)} * method until it returns {@code true}. */ @Override public void awaitRelease(CancellationToken cancelToken) { while (!tryAwaitRelease(cancelToken, Long.MAX_VALUE, TimeUnit.NANOSECONDS)) { // Repeat until it has been released, or throws an exception. } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy