java.lang.Object | |
↳ | com.facebook.common.references.SharedReference<T> |
A shared-reference class somewhat similar to c++ shared_ptr. The underlying value is reference counted, and when the count drops to zero, the underlying value is "disposed"
Unlike the c++ implementation, which provides for a bunch of syntactic sugar with copy constructors and destructors, Java does not provide the equivalents. So we instead have the explicit addReference() and deleteReference() calls, and we need to be extremely careful about using these in the presence of exceptions, or even otherwise.
Despite the extra (and clunky) method calls, this is still worthwhile in many cases to avoid the overhead of garbage collection.
The somewhat clunky rules are 1. If a function returns a SharedReference, it must guarantee
that the reference count is at least 1. In the case where a SharedReference is being constructed
and returned, the SharedReference constructor will already set the ref count to 1. 2. If a
function calls another function with a shared-reference parameter, 2.1 The caller must ensure
that the reference is valid for the duration of the invocation. 2.2 The callee *is not*
responsible for the cleanup of the reference. 2.3 If the callee wants to keep the reference
around even after the call returns (for example, stashing it away in a map), then it should
"clone" the reference by invoking addReference()
Example #1 (function with a shared reference parameter): void foo(SharedReference r, ...) { // first assert that the reference is valid Preconditions.checkArgument(SharedReference.isValid(r)); ... // do something with the contents of r ... // do not increment/decrement the ref count }
Example #2 (function with a shared reference parameter that keeps around the shared ref) void foo(SharedReference r, ...) { // first assert that the reference is valid Preconditions.checkArgument(SharedReference.isValid(r)); ... // increment ref count r.addReference(); // stash away the reference ... return; }
Example #3 (function with a shared reference parameter that passes along the reference to another function) void foo(SharedReference r, ...) { // first assert that the reference is valid Preconditions.checkArgument(SharedReference.isValid(r)); ... bar(r, ...); // call to other function ... }
Example #4 (function that returns a shared reference) SharedReference foo(...) { // do something ... // create a new shared reference (refcount automatically at 1) SharedReference r = new SharedReference(x); // return this shared reference return r; }
Example #5 (function with a shared reference parameter that returns the shared reference) void foo(SharedReference r, ...) { // first assert that the reference is valid Preconditions.checkArgument(SharedReference.isValid(r)); ... // increment ref count before returning r.addReference(); return r; }
Nested Classes | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
class | SharedReference.NullReferenceException | The moral equivalent of NullPointerException for SharedReference. |
Public Constructors | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
SharedReference(T value, ResourceReleaser<T> resourceReleaser)
Construct a new shared-reference that will 'own' the supplied
value . |
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
synchronized void |
addReference()
Bump up the reference count for the shared reference Note: The reference must be valid (aka not
null) at this point
| ||||||||||
synchronized boolean |
addReferenceIfValid()
Bump up the reference count for the shared reference if the shared-reference is valid.
| ||||||||||
void |
deleteReference()
Decrement the reference count for the shared reference.
| ||||||||||
synchronized boolean | deleteReferenceIfValid() | ||||||||||
synchronized T |
get()
Get the current referenced value.
| ||||||||||
synchronized int |
getRefCountTestOnly()
A test-only method to get the ref count DO NOT USE in regular code
| ||||||||||
static boolean |
isValid(SharedReference<?> ref)
Checks if the shared-reference is valid i.e.
| ||||||||||
synchronized boolean |
isValid()
Checks if this shared-reference is valid i.e.
| ||||||||||
static String | reportData() |
[Expand]
Inherited Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
From class
java.lang.Object
|
Construct a new shared-reference that will 'own' the supplied value
. The reference
count will be set to 1. When the reference count decreases to zero resourceReleaser
will be used to release the value
value | non-null value to manage |
---|---|
resourceReleaser | non-null ResourceReleaser for the value |
Bump up the reference count for the shared reference Note: The reference must be valid (aka not null) at this point
Bump up the reference count for the shared reference if the shared-reference is valid.
Decrement the reference count for the shared reference. If the reference count drops to zero, then dispose of the referenced value
Get the current referenced value. Null if there's no value.
A test-only method to get the ref count DO NOT USE in regular code
Checks if the shared-reference is valid i.e. its reference count is greater than zero
Checks if this shared-reference is valid i.e. its reference count is greater than zero.