Skip to content

Instantly share code, notes, and snippets.

@cap5lut
Last active January 10, 2019 14:07
Show Gist options
  • Save cap5lut/1f9d30fa97f6635142dc7ea2b6433879 to your computer and use it in GitHub Desktop.
Save cap5lut/1f9d30fa97f6635142dc7ea2b6433879 to your computer and use it in GitHub Desktop.
Lazy instatiation, which will work lock-free once the instance is created.
package com.github.cap5lut.util;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
/**
* Lazy instance creation.
* @param <T> Instance type.
*/
public class Lazy<T> {
/**
* Actual getter.
*/
private volatile Supplier<T> getter = this::creator;
/**
* Actual instance.
*/
private volatile T instance;
/**
* Instance factory.
*/
private Supplier<T> factory;
/**
* Creates a new lazy instance.
* @param factory Instance factory.
*/
public Lazy(Supplier<T> factory) {
this.factory = Objects.requireNonNull(factory, "factory must not be null");
}
/**
* Creates and gets the instance.
* @return Created instance.
*/
private synchronized T creator() {
if(instance != null) {
return instance;
}
instance = Objects.requireNonNull(factory.get(), "created instance must not be null");
getter = this::getter;
factory = null;
return instance;
}
/**
* Gets the instance.
* @return Instance.
*/
private T getter() {
return instance;
}
/**
* Gets the instance. If the instance was not created yet, it will be created.
* @return Instance.
*/
public T getOrCreate() {
return getter.get();
}
/**
* Gets the instance, if created or else an empty {@link Optional}.
* @return {@code Optional} filled with the instance, or an empty {@code Optional}, if the instance was not created
* yet.
*/
public Optional<T> get() {
return Optional.ofNullable(instance);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment