public class

SharedReference

extends Object
java.lang.Object
   ↳ com.facebook.common.references.SharedReference<T>

Class Overview

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; }

Summary

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

Public Constructors

public SharedReference (T value, ResourceReleaser<T> resourceReleaser)

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

Parameters
value non-null value to manage
resourceReleaser non-null ResourceReleaser for the value

Public Methods

public synchronized void addReference ()

Bump up the reference count for the shared reference Note: The reference must be valid (aka not null) at this point

public synchronized boolean addReferenceIfValid ()

Bump up the reference count for the shared reference if the shared-reference is valid.

public void deleteReference ()

Decrement the reference count for the shared reference. If the reference count drops to zero, then dispose of the referenced value

public synchronized boolean deleteReferenceIfValid ()

public synchronized T get ()

Get the current referenced value. Null if there's no value.

Returns
  • the referenced value

public synchronized int getRefCountTestOnly ()

A test-only method to get the ref count DO NOT USE in regular code

public static boolean isValid (SharedReference<?> ref)

Checks if the shared-reference is valid i.e. its reference count is greater than zero

Returns
  • true if the shared reference is valid

public synchronized boolean isValid ()

Checks if this shared-reference is valid i.e. its reference count is greater than zero.

Returns
  • true if shared reference is valid

public static String reportData ()