实现单例模式思路:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。(来自维基百科)
总结一下要点:
1. 只能拥有一个对象。
2. 构造函数私有 以保证不能创建多余的对象。
3. 在类内创建一个对象,将其引用作为成员变量,但构造函数是 私有的,无法new对象,只能将类内对象的引用加上static 修饰符,以保证可以直接用类加载调用。
4. 这个对象作为成员变量,一般为private,所以有对应的get 方法。
5. getInstance() 方法必须为静态方法。
饿汉式
class Singleton {
private Singleton() {}
private static final Singleton singleton = new Singleton();
public static Singleton getInstance() {
return singleton;
}
}
最简单的一种写法,类加载时直接new 出一个对象。
懒汉式 (延迟加载)
1 . 线程不安全写法,多线程时可能会同时new 对象
class Singleton {
private Singleton() {}
private static Singleton singleton = null;
public static Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
2 . 线程安全写法,但效率太低,一般不用
class Singleton {
private Singleton() {}
private static Singleton singleton = null;
public static synchronized Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
3 . 双重校验锁,较常用,解决了线程问题和效率问题
class Singleton {
private Singleton() {}
private static Singleton singleton = null;
public static Singleton getInstance(){
if(singleton == null){
synchronized(Singleton.class) {
if(singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
4 . 静态内部类 ,好像也比较常用
class Singleton {
private Singleton() {
System.out.println("singleton create");
}
private static class InstanceHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return InstanceHolder.INSTANCE;
}
}