设计模式:单例模式(Singleton)

简介:   单例模式在23个设计模式中算得上是最简单的一个了,也许你会有异议,那就换成“最简单之一”,这样就严谨了很多。   单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

  单例模式在23个设计模式中算得上是最简单的一个了,也许你会有异议,那就换成“最简单之一”,这样就严谨了很多。
  单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
  适用性:当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
这里写图片描述

单例模式有5中写法(线程安全):
1. 饿汉式
2. 懒汉式
3. 双检索(DCL)
4. 占位符式
5. 枚举式
下面分别展示这五种写法(详细内容可以参考博主的《singleton模式四种线程安全的实现》和《如何防止单例模式被JAVA反射攻击》)


饿汉式

public class EagerSingleton {  
        // jvm保证在任何线程访问uniqueInstance静态变量之前一定先创建了此实例  
        private static EagerSingleton uniqueInstance = new EagerSingleton();  

        // 私有的默认构造子,保证外界无法直接实例化  
        private EagerSingleton() {  
        }  

        // 提供全局访问点获取唯一的实例  
        public static EagerSingleton getInstance() {  
                return uniqueInstance;  
        }  
}

懒汉式

public class LazySingleton {  
        private static LazySingleton uniqueInstance;  

        private LazySingleton() {  
        }  

        public static synchronized LazySingleton getInstance() {  
                if (uniqueInstance == null)  
                        uniqueInstance = new LazySingleton();  
                return uniqueInstance;  
        }  
} 

双检锁

(博主不建议使用)

public class DoubleCheckedLockingSingleton {  
        // java中使用双重检查锁定机制,由于Java编译器和JIT的优化的原因系统无法保证我们期望的执行次序。  
        // 在java5.0修改了内存模型,使用volatile声明的变量可以强制屏蔽编译器和JIT的优化工作  
        private volatile static DoubleCheckedLockingSingleton uniqueInstance;  

        private DoubleCheckedLockingSingleton() {  
        }  

        public static DoubleCheckedLockingSingleton getInstance() {  
                if (uniqueInstance == null) {  
                        synchronized (DoubleCheckedLockingSingleton.class) {  
                                if (uniqueInstance == null) {  
                                        uniqueInstance = new DoubleCheckedLockingSingleton();  
                                }  
                        }  
                }  
                return uniqueInstance;  
        }  
}

占位符式

public class LazyInitHolderSingleton {  
        private LazyInitHolderSingleton() {  
        }  

        private static class SingletonHolder {  
                private static final LazyInitHolderSingleton INSTANCE = new LazyInitHolderSingleton();  
        }  

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

枚举式

有关枚举的详细资料可以参考《Java枚举类型enum

public enum SingletonClass
{
    INSTANCE;
}

Jdk中的单例模式:
java.lang.Runtime#getRuntime()


总结

枚举式式最简单最优秀的单例写法,可以防止反射工具(详细参考《如何防止单例模式被JAVA反射攻击》)和序列化破坏(详细参考《JAVA序列化 》),《Effective Java》的作者Joshua Bloch推荐使用这种写法,博主也认为这种写法不错,只是用的人较少,没有普遍性,建议编程时采用占位符式(不能防止反射和序列化破坏),当然写成枚举式就更好啦。

参考资料
1. 《singleton模式四种线程安全的实现
2. 《如何防止单例模式被JAVA反射攻击
3. 《JAVA序列化
4. 《Java枚举类型enum
5. 《Effective Java(Second Edition)》Joshua Bloch.
6. 《细数JDK里的设计模式

目录
相关文章
|
19天前
|
设计模式 安全 Java
【设计模式系列笔记】单例模式
单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点,以便全局范围内访问这个实例。单例模式的目标是限制一个类的实例化,确保在整个应用程序中只有一个实例存在,并提供对这个唯一实例的全局访问点。这对于控制对资源的访问、限制特定类的实例数量等场景非常有用。
122 5
|
1月前
|
设计模式 PHP
php设计模式--单例模式(三)
php设计模式--单例模式(三)
13 0
|
12天前
|
设计模式 安全 Java
【JAVA】Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式
【JAVA】Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式
|
10天前
|
设计模式 安全 Java
【设计模式学习】单例模式和工厂模式
【设计模式学习】单例模式和工厂模式
|
10天前
|
设计模式 安全 Java
|
12天前
|
设计模式 存储 安全
Java 设计模式:深入单例模式的理解与应用
【4月更文挑战第27天】单例模式是一种常用的设计模式,在 Java 开发中扮演着重要角色。此模式的主要目的是保证一个类只有一个实例,并提供一个全局访问点。
19 0
|
15天前
|
设计模式 安全 Java
[设计模式Java实现附plantuml源码~创建型] 确保对象的唯一性~单例模式
[设计模式Java实现附plantuml源码~创建型] 确保对象的唯一性~单例模式
|
16天前
|
设计模式 安全 测试技术
[设计模式 Go实现] 创建型~单例模式
[设计模式 Go实现] 创建型~单例模式
|
25天前
|
设计模式 存储 Java
Java设计模式:解释一下单例模式(Singleton Pattern)。
`Singleton Pattern`是Java中的创建型设计模式,确保类只有一个实例并提供全局访问点。它通过私有化构造函数,用静态方法返回唯一的实例。类内静态变量存储此实例,对外仅通过静态方法访问。
16 1
|
27天前
|
设计模式 安全 Java
小谈设计模式(22)—单例模式
小谈设计模式(22)—单例模式