Package com.google.common.base
Class FinalizableReferenceQueue
java.lang.Object
com.google.common.base.FinalizableReferenceQueue
- All Implemented Interfaces:
Closeable
,AutoCloseable
A reference queue with an associated background thread that dequeues references and invokes
FinalizableReference.finalizeReferent()
on them.
Keep a strong reference to this object until all of the associated referents have been
finalized. If this object is garbage collected earlier, the backing thread will not invoke
finalizeReferent()
on the remaining references.
As an example of how this is used, imagine you have a class MyServer
that creates a
ServerSocket
, and you would like to ensure that the
ServerSocket
is closed even if the MyServer
object is garbage-collected without calling
its close
method. You could use a finalizer to accomplish this, but that has a
number of well-known problems. Here is how you might use this class instead:
public class MyServer implements Closeable {
private static final FinalizableReferenceQueue frq = new FinalizableReferenceQueue();
// You might also share this between several objects.
private static final Set<Reference<?>> references = Sets.newConcurrentHashSet();
// This ensures that the FinalizablePhantomReference itself is not garbage-collected.
private final ServerSocket serverSocket;
private MyServer(...) {
...
this.serverSocket = new ServerSocket(...);
...
}
public static MyServer create(...) {
MyServer myServer = new MyServer(...);
final ServerSocket serverSocket = myServer.serverSocket;
Reference<?> reference = new FinalizablePhantomReference<MyServer>(myServer, frq) {
public void finalizeReferent() {
references.remove(this):
if (!serverSocket.isClosed()) {
...log a message about how nobody called close()...
try {
serverSocket.close();
} catch (IOException e) {
...
}
}
}
};
references.add(reference);
return myServer;
}
public void close() {
serverSocket.close();
}
}
- Since:
- 2.0
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static class
Try to load Finalizer in its own class loader.(package private) static class
Loads Finalizer directly using the current class loader.(package private) static interface
Loads Finalizer.class.(package private) static class
Tries to load Finalizer from the system class loader. -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final String
(package private) final PhantomReference
<Object> private static final Logger
(package private) final ReferenceQueue
<Object> The actual reference queue that our background thread will poll.private static final Method
Reference to Finalizer.startFinalizer().(package private) final boolean
Whether or not the background thread started successfully. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription(package private) void
cleanUp()
Repeatedly dequeues references from the queue and invokesFinalizableReference.finalizeReferent()
on them until the queue is empty.void
close()
(package private) static Method
getStartFinalizer
(Class<?> finalizer) Looks up Finalizer.startFinalizer().private static Class
<?> Iterates through the given loaders until it finds one that can load Finalizer.
-
Field Details
-
logger
-
FINALIZER_CLASS_NAME
- See Also:
-
startFinalizer
Reference to Finalizer.startFinalizer(). -
queue
The actual reference queue that our background thread will poll. -
frqRef
-
threadStarted
final boolean threadStartedWhether or not the background thread started successfully.
-
-
Constructor Details
-
FinalizableReferenceQueue
public FinalizableReferenceQueue()Constructs a new queue.
-
-
Method Details
-
close
public void close()- Specified by:
close
in interfaceAutoCloseable
- Specified by:
close
in interfaceCloseable
-
cleanUp
void cleanUp()Repeatedly dequeues references from the queue and invokesFinalizableReference.finalizeReferent()
on them until the queue is empty. This method is a no-op if the background thread was created successfully. -
loadFinalizer
Iterates through the given loaders until it finds one that can load Finalizer.- Returns:
- Finalizer.class
-
getStartFinalizer
Looks up Finalizer.startFinalizer().
-