Utility class to safely share instances of a certain type across multiple threads, while periodically refreshing them. This class ensures each reference is closed only once all threads have finished using it. It is recommended to consult the documentation of
ReferenceManagerimplementations for their
- WARNING: This API is experimental and might change in incompatible ways in the next release.
Nested Class Summary
Nested Classes Modifier and Type Class Description
ReferenceManager.RefreshListenerUse to receive notification when a refresh has finished.
Constructors Constructor Description
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description
acquire()Obtain the current reference.
addListener(ReferenceManager.RefreshListener listener)Adds a listener, to be notified when a reference is refreshed/swapped.
afterClose()Called after close(), so subclass can free any resources.
afterMaybeRefresh()Called after a refresh was attempted, regardless of whether a new reference was in fact created.
close()Closes this ReferenceManager to prevent future
protected abstract void
decRef(G reference)Decrement reference counting on the given reference.
protected abstract int
getRefCount(G reference)Returns the current reference count of the given reference.
protected abstract G
refreshIfNeeded(G referenceToRefresh)Refresh the given reference if needed.
release(G reference)Release the reference previously obtained via
removeListener(ReferenceManager.RefreshListener listener)Remove a listener added with
protected abstract boolean
tryIncRef(G reference)Try to increment reference counting on the given reference.
protected volatile G current
protected abstract void decRef(G reference) throws IOExceptionDecrement reference counting on the given reference.
IOException- if reference decrement on the given resource failed.
protected abstract G refreshIfNeeded(G referenceToRefresh) throws IOExceptionRefresh the given reference if needed. Returns
nullif no refresh was needed, otherwise a new refreshed reference.
protected abstract boolean tryIncRef(G reference) throws IOExceptionTry to increment reference counting on the given reference. Return true if the operation was successful.
public final G acquire() throws IOExceptionObtain the current reference. You must match every call to acquire with one call to
release(G); it's best to do so in a finally clause, and set the reference to
nullto prevent accidental usage after it has been released.
public final void close() throws IOExceptionCloses this ReferenceManager to prevent future
acquiring. A reference manager should be closed if the reference to the managed resource should be disposed or the application using the
ReferenceManageris shutting down. The managed resource might not be released immediately, if the
ReferenceManageruser is holding on to a previously
acquiredreference. The resource will be released once when the last reference is
released. Those references can still be used as if the manager was still active.
protected abstract int getRefCount(G reference)Returns the current reference count of the given reference.
protected void afterClose() throws IOExceptionCalled after close(), so subclass can free any resources.
public final boolean maybeRefresh() throws IOExceptionYou must call this (or
maybeRefreshBlocking()), periodically, if you want that
acquire()will return refreshed instances.
Threads: it's fine for more than one thread to call this at once. Only the first thread will attempt the refresh; subsequent threads will see that another thread is already handling refresh and will return immediately. Note that this means if another thread is already refreshing then subsequent threads will return right away without waiting for the refresh to complete.
If this method returns true it means the calling thread either refreshed or that there were no changes to refresh. If it returns false it means another thread is currently refreshing.
public final void maybeRefreshBlocking() throws IOExceptionYou must call this (or
maybeRefresh()), periodically, if you want that
acquire()will return refreshed instances.
maybeRefresh(), if another thread is currently refreshing, this method blocks until that thread completes. It is useful if you want to guarantee that the next call to
acquire()will return a refreshed instance. Otherwise, consider using the non-blocking
protected void afterMaybeRefresh() throws IOExceptionCalled after a refresh was attempted, regardless of whether a new reference was in fact created.
IOException- if a low level I/O exception occurs
public final void release(G reference) throws IOExceptionRelease the reference previously obtained via
NOTE: it's safe to call this after
public void addListener(ReferenceManager.RefreshListener listener)Adds a listener, to be notified when a reference is refreshed/swapped.