Android源码中的一种单例实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package android.util;

/**
 * Singleton helper class for lazily initialization.
 *
 * Modeled after frameworks/base/include/utils/Singleton.h
 *
 * @hide
 */
public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
} 
    

正常懒汉单例

1
2
3
4
5
6
7
8
9
10
11
12
public class SingletonDemo {
    private static SingletonDemo mInstance;

    public static final SingletonDemo get() {
        synchronized (SingletonDemo.class) {
            if (mInstance == null) {
                mInstance = new SingletonDemo();
            }
            return mInstance;
        }
    }
} 

懒汉+双重校验单例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class SingletonDemo {
    private static SingletonDemo mInstance;

    public static final SingletonDemo get() {
        if (mInstance == null) {
            synchronized (SingletonDemo.class) {
                if (mInstance == null) {
                    mInstance = new SingletonDemo();
                }
            }
        }
        return mInstance;
    }
} 

变种懒汉单例

1
2
3
4
5
6
7
8
9
10
11
12
public class SingletonDemo {

    public static final SingletonDemo get() {
        return INSTANCE.get();
    }

    private static final Singleton<SingletonDemo> INSTANCE = new Singleton<SingletonDemo>() {
        protected SingletonDemo create() {
            return new SingletonDemo();
        }
    };
}

懒汉式单例一般都会再加个双重校验的判断,避免每次调用get()都加锁,影响性能,Android源码中Singleton.java工具类并没有做双重校验(看了下googlesource中的Singleton.java,也是6年前提交的代码了),所以我们在将Singleton.java拷贝出来使用的时候可以加个双重校验优化下。Singleton.java封装了create,get模版,及get中的校验逻辑,从而SingletonDemo中的实现代码就可以更加的简单:1.create()一个单例对象,2.在需要的时候get()。