序
本文主要介绍如何利用Guava的Suppliers.memoize实现单例。
实例
/*** 利用Suppliers.memoize实现单例* Created by xixicat on 15/12/25.*/
public class SuppilerSingletonTest {class HeavyObject{public HeavyObject() {System.out.println("being created");}}class ObjectSuppiler implements Supplier<HeavyObject>{@Overridepublic HeavyObject get() {return new HeavyObject();}}/*** 每次都new一次*/@Testpublic void testNotSingleton(){Supplier<HeavyObject> notCached = new ObjectSuppiler();for(int i=0;i<5;i++){notCached.get();}}/*** 单例*/@Testpublic void testSingleton(){Supplier<HeavyObject> notCached = new ObjectSuppiler();Supplier<HeavyObject> cachedSupplier = Suppliers.memoize(notCached);for(int i=0;i<5;i++){cachedSupplier.get();}}
}
Suppliers.memoize方法
/*** Returns a supplier which caches the instance retrieved during the first* call to {@code get()} and returns that value on subsequent calls to* {@code get()}. See:* <a href="http://en.wikipedia.org/wiki/Memoization">memoization</a>** <p>The returned supplier is thread-safe. The supplier's serialized form* does not contain the cached value, which will be recalculated when {@code* get()} is called on the reserialized instance.** <p>If {@code delegate} is an instance created by an earlier call to {@code* memoize}, it is returned directly.*/public static <T> Supplier<T> memoize(Supplier<T> delegate) {return (delegate instanceof MemoizingSupplier)? delegate: new MemoizingSupplier<T>(Preconditions.checkNotNull(delegate));}@VisibleForTestingstatic class MemoizingSupplier<T> implements Supplier<T>, Serializable {final Supplier<T> delegate;transient volatile boolean initialized;// "value" does not need to be volatile; visibility piggy-backs// on volatile read of "initialized".transient T value;MemoizingSupplier(Supplier<T> delegate) {this.delegate = delegate;}@Override public T get() {// A 2-field variant of Double Checked Locking.if (!initialized) {synchronized (this) {if (!initialized) {T t = delegate.get();value = t;initialized = true;return t;}}}return value;}@Override public String toString() {return "Suppliers.memoize(" + delegate + ")";}private static final long serialVersionUID = 0;}
参考
Guava Explained