2013/04/15

Cached Singleton by java.lang.ref.Reference

In Java, Using only-one instance, the following "Singleton" program is written, you know.
And this program uses a static inner class. This pattern is well known as "Lazy loading".
public class Singleton {
    private Singleton(){}

    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder {
        public static final Singleton INSTANCE = new Singleton();
    }
}
But the Singleton instance is not reclaimed without the ClassLoader is not disposed, because the ClassLoader holds the Shingleton class. So I will suggest how to create reclaimable Singleton class. The following program uses java.lang.ref.WeakReference.
public class Singleton {
    private Singleton() {}

    public static Singleton getInstance() {
        synchronized(SingletonHolder.class){
            Singleton referent = SingletonHolder.INSTANCE.get();
            if(referent == null){
                referent = new Singleton();
                SingletonHolder.INSTANCE = new WeakReference<>(referent);
            }
            return referent;
        }
    }

    private static class SingletonHolder {
        public static Reference<Singleton> INSTANCE = new WeakReference<>(new Singleton());
    }
}
If outer program does not hold a Strong Reference to Singleton instance, Singleton instance will be reclaimed whenever a garbage collection runs. A life of Singleton instance will be shorter and memory usage of the Java VM will be decreased.

Note that a return value of WeakReference.get() will be changed after a garbage collection. So the return value of WeakReferent.get() should be substituted for a local variable at line 6 of the above program. If the referent is null, a new Singleton instance is substituted for the same local variable at line 8. These two substitution is important, because of holding "Strong Reference". At last, getInstance() will return a valid Singleton instance certainly.

If you want a life of Singleton instance to be longer, change WeakReference class to SoftReference class at line 9 and 16.

0 件のコメント:

コメントを投稿