Java面向对象设计模式-单例模式
2020-05-28
589
0
单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点,有多重实现方式。
一、饿汉式单例模式,构造方法私有化,在加载类Singleton时实例化一个对象,并提供公有的getInstance()方法获取实例:
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return singleton;
}
}
1
2
3
4
5
6
7
8
9
10
publicclassSingleton{
privatestaticSingletonsingleton=newSingleton();
privateSingleton(){
}
publicstaticSingletongetInstance(){
returnsingleton;
}
}
二、懒汉式单例模式,构造方法私有化,调用getInstance()时,如果单例对象未实例化则实例化后返回,如果已实例化直接返回。
由于线程安全,存在多个线程多次实例化的情况,加上synchronized同步实例化代码块后,还是存在多次实例化的情况,所以采用Double Check,同步代码块内层也进行空判断。
new实例化操作不是原子操作,分为三步如注释,可能导致实例不为null,另一个线程直接返回未初始化完成的实例导致错误,所以实例使用volatile保证初始化操作的线程安全。
public class Singleton {
private static volatile Singleton singleton;
private Singleton() {
}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
/*
* 1.给singleton分配内存空间
* 2.调用Singleton的构造方法初始化singleton
* 3.将singleton对象指向分配的内存空间(执行完这步singleton不为null)
* 2和3顺序不能保证,volatile解决
*/
singleton = new Singleton();// 非原子操作
}
}
}
return singleton;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
publicclassSingleton{
privatestaticvolatileSingletonsingleton;
privateSingleton(){
}
publicstaticSingletongetInstance(){
if(singleton==null){
synchronized(Singleton.class){
if(singleton==null){
/*
* 1.给singleton分配内存空间
* 2.调用Singleton的构造方法初始化singleton
* 3.将singleton对象指向分配的内存空间(执行完这步singleton不为null)
* 2和3顺序不能保证,volatile解决
*/
singleton=newSingleton();// 非原子操作
}
}
}
returnsingleton;
}
}
三、静态内部类式单例模式,JVM类装载保证线程安全,调用getInstance()时才实例化:
public class SingletonAnonymousInnerClass {
private SingletonAnonymousInnerClass() {
}
private static class SingletonInstance {
private static final SingletonAnonymousInnerClass singleton = new SingletonAnonymousInnerClass();
}
public static SingletonAnonymousInnerClass getInstance() {
return SingletonInstance.singleton;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
publicclassSingletonAnonymousInnerClass{
privateSingletonAnonymousInnerClass(){
}
privatestaticclassSingletonInstance{
privatestaticfinalSingletonAnonymousInnerClasssingleton=newSingletonAnonymousInnerClass();
}
publicstaticSingletonAnonymousInnerClassgetInstance(){
returnSingletonInstance.singleton;
}
}
四、枚举式单例模式,类加载时才初始化实例同样线程安全。
序列化与反序列化不会新创建实例破坏单例,序列化通过getName()方法,反序列化通过Enum的valueOf()方法。
无法通过反射创建实例破坏单例,抛出IllegalArgumentException。
public class SingletonEnum {
public enum singleton {
INSTANCE;
}
}
1
2
3
4
5
publicclassSingletonEnum{
publicenumsingleton{
INSTANCE;
}
}