单例模式
什么是单例?表面意思就是一个实例,只希望有一个这样的实例存在。
Ensure a class has only one instance,and provide a global point of access to it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @startuml singleton class Singleton{ - static final Singleton singleton = new Singleton() - Singleton() + static Singleton getSingleton() }
class Client{
}
Client --> Singleton
note "通过 Singleton.getSingleton()方式访问" as N1 N1 .. Client
@enduml
|
UML类图:
懒加载(懒汉)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class Singleton { private volatile static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){ if (instance == null){ synchronized (Singleton.class){ if (instance == null){ instance = new Singleton(); } } } return instance; } }
|
静态内部类
1 2 3 4 5 6 7 8 9 10 11 12
| public class Singleton { private Singleton(){}
private static class SingletonHolder{ public static final Singleton INSTANCE = new Singleton(); }
public static Singleton getInstance(){ return SingletonHolder.INSTANCE; } }
|
饿汉
1 2 3 4 5 6 7 8 9 10
| public class Singleton { private static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){ return instance; } }
|
枚举
enum
为 final
,有且仅有private
的构造器,自由序列化,线程安全,保证单例
JVM可以保证枚举类型不可被反射
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public enum Singleton { INSTANCE{ @Override protected void answer() { System.out.println("yeah"); } };
public void ask(){ System.out.println("hello world"); }
protected abstract void answer(); }
|
测试代码
1 2 3 4 5 6 7 8 9 10
| public class Run { public static void main(String[] args) { Singleton instance = Singleton.INSTANCE; Singleton instance1 = Singleton.INSTANCE;
System.out.println(instance.hashCode()); System.out.println(instance1.hashCode()); System.out.println(instance.equals(instance1)); } }
|