Class ReferenceManager<G>
- java.lang.Object
-
- org.apache.lucene.search.ReferenceManager<G>
-
- All Implemented Interfaces:
java.io.Closeable,java.lang.AutoCloseable
- Direct Known Subclasses:
ReaderManager,SearcherManager
public abstract class ReferenceManager<G> extends java.lang.Object implements java.io.CloseableUtility 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 ofReferenceManagerimplementations for theirmaybeRefresh()semantics.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interfaceReferenceManager.RefreshListenerUse to receive notification when a refresh has finished.
-
Field Summary
Fields Modifier and Type Field Description protected Gcurrentprivate static java.lang.StringREFERENCE_MANAGER_IS_CLOSED_MSGprivate java.util.List<ReferenceManager.RefreshListener>refreshListenersprivate java.util.concurrent.locks.LockrefreshLock
-
Constructor Summary
Constructors Constructor Description ReferenceManager()
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description Gacquire()Obtain the current reference.voidaddListener(ReferenceManager.RefreshListener listener)Adds a listener, to be notified when a reference is refreshed/swapped.protected voidafterClose()Called after close(), so subclass can free any resources.protected voidafterMaybeRefresh()Called after a refresh was attempted, regardless of whether a new reference was in fact created.voidclose()Closes this ReferenceManager to prevent futureacquiring.protected abstract voiddecRef(G reference)Decrement reference counting on the given reference.private voiddoMaybeRefresh()private voidensureOpen()protected abstract intgetRefCount(G reference)Returns the current reference count of the given reference.booleanmaybeRefresh()You must call this (ormaybeRefreshBlocking()), periodically, if you want thatacquire()will return refreshed instances.voidmaybeRefreshBlocking()You must call this (ormaybeRefresh()), periodically, if you want thatacquire()will return refreshed instances.private voidnotifyRefreshListenersBefore()private voidnotifyRefreshListenersRefreshed(boolean didRefresh)protected abstract GrefreshIfNeeded(G referenceToRefresh)Refresh the given reference if needed.voidrelease(G reference)Release the reference previously obtained viaacquire().voidremoveListener(ReferenceManager.RefreshListener listener)Remove a listener added withaddListener(RefreshListener).private voidswapReference(G newReference)protected abstract booleantryIncRef(G reference)Try to increment reference counting on the given reference.
-
-
-
Field Detail
-
REFERENCE_MANAGER_IS_CLOSED_MSG
private static final java.lang.String REFERENCE_MANAGER_IS_CLOSED_MSG
- See Also:
- Constant Field Values
-
current
protected volatile G current
-
refreshLock
private final java.util.concurrent.locks.Lock refreshLock
-
refreshListeners
private final java.util.List<ReferenceManager.RefreshListener> refreshListeners
-
-
Method Detail
-
ensureOpen
private void ensureOpen()
-
swapReference
private void swapReference(G newReference) throws java.io.IOException
- Throws:
java.io.IOException
-
decRef
protected abstract void decRef(G reference) throws java.io.IOException
Decrement reference counting on the given reference.- Throws:
java.io.IOException- if reference decrement on the given resource failed.
-
refreshIfNeeded
protected abstract G refreshIfNeeded(G referenceToRefresh) throws java.io.IOException
Refresh the given reference if needed. Returnsnullif no refresh was needed, otherwise a new refreshed reference.- Throws:
AlreadyClosedException- if the reference manager has beenclosed.java.io.IOException- if the refresh operation failed
-
tryIncRef
protected abstract boolean tryIncRef(G reference) throws java.io.IOException
Try to increment reference counting on the given reference. Return true if the operation was successful.- Throws:
AlreadyClosedException- if the reference manager has beenclosed.java.io.IOException
-
acquire
public final G acquire() throws java.io.IOException
Obtain the current reference. You must match every call to acquire with one call torelease(G); it's best to do so in a finally clause, and set the reference tonullto prevent accidental usage after it has been released.- Throws:
AlreadyClosedException- if the reference manager has beenclosed.java.io.IOException
-
close
public final void close() throws java.io.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 theReferenceManageris shutting down. The managed resource might not be released immediately, if theReferenceManageruser is holding on to a previouslyacquiredreference. The resource will be released once when the last reference isreleased. Those references can still be used as if the manager was still active.Applications should not
acquirenew references from this manager once this method has been called.Acquiringa resource on a closedReferenceManagerwill throw anAlreadyClosedException.- Specified by:
closein interfacejava.lang.AutoCloseable- Specified by:
closein interfacejava.io.Closeable- Throws:
java.io.IOException- if the underlying reader of the current reference could not be closed
-
getRefCount
protected abstract int getRefCount(G reference)
Returns the current reference count of the given reference.
-
afterClose
protected void afterClose() throws java.io.IOExceptionCalled after close(), so subclass can free any resources.- Throws:
java.io.IOException- if the after close operation in a sub-class throws anIOException
-
doMaybeRefresh
private void doMaybeRefresh() throws java.io.IOException- Throws:
java.io.IOException
-
maybeRefresh
public final boolean maybeRefresh() throws java.io.IOExceptionYou must call this (ormaybeRefreshBlocking()), periodically, if you want thatacquire()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.
- Throws:
java.io.IOException- if refreshing the resource causes anIOExceptionAlreadyClosedException- if the reference manager has beenclosed.
-
maybeRefreshBlocking
public final void maybeRefreshBlocking() throws java.io.IOExceptionYou must call this (ormaybeRefresh()), periodically, if you want thatacquire()will return refreshed instances.Threads: unlike
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 toacquire()will return a refreshed instance. Otherwise, consider using the non-blockingmaybeRefresh().- Throws:
java.io.IOException- if refreshing the resource causes anIOExceptionAlreadyClosedException- if the reference manager has beenclosed.
-
afterMaybeRefresh
protected void afterMaybeRefresh() throws java.io.IOExceptionCalled after a refresh was attempted, regardless of whether a new reference was in fact created.- Throws:
java.io.IOException- if a low level I/O exception occurs
-
release
public final void release(G reference) throws java.io.IOException
Release the reference previously obtained viaacquire().NOTE: it's safe to call this after
close().- Throws:
java.io.IOException- if the release operation on the given resource throws anIOException
-
notifyRefreshListenersBefore
private void notifyRefreshListenersBefore() throws java.io.IOException- Throws:
java.io.IOException
-
notifyRefreshListenersRefreshed
private void notifyRefreshListenersRefreshed(boolean didRefresh) throws java.io.IOException- Throws:
java.io.IOException
-
addListener
public void addListener(ReferenceManager.RefreshListener listener)
Adds a listener, to be notified when a reference is refreshed/swapped.
-
removeListener
public void removeListener(ReferenceManager.RefreshListener listener)
Remove a listener added withaddListener(RefreshListener).
-
-