Wiki

Clone wiki

atlassian-util-concurrent / LazyReference_and_ResettableLazyReference

LazyReference is a reference that does not create the actual instance until it is required. It has *final* semantics and cannot be changed once created. The instance it holds is created by the first thread that calls get() - any other thread calling get() at the same time will block until the first thread completes.

To use it you simply implement the create() method and return the desired instance. For instance:

final LazyReference<MyObject> ref = new LazyReference() {
    protected MyObject create() throws Exception {
        return new MyObject(); // do expensive object construction here
    }
};

If an exception is thrown from the create() method then get() throws an InitializationException with the original exception as the causal exception.

  • Performance note:* Importantly, the get() method is not synchronized (essentially volatile instead), which for a highly requested object means there is no chance of blocking. In production we have seen this to be a massive advantage.

LazyReference.java

ResettableLazyReference

There is also a ResettableLazyReference that adds the reset() method for situations where a previously calculated value may need to be cleared. Usage is identical to LazyReference apart from the type.

Note that calling reset() does not affect the value currently executing or any threads currently waiting for that value, only any subsequent calls to get() (ie. ones that _happen-after_ reset().

ResettableLazyReference.java

Updated