设计模式:单例模式(Singleton)
2016-03-24 09:39
429 查看
单例模式在23个设计模式中算得上是最简单的一个了,也行你会有异议,那就换成“最简单之一”,这样就严谨了很多。
单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
适用性:当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
单例模式有5中写法(线程安全):
1. 饿汉式
2. 懒汉式
3. 双检索(DCL)
4. 占位符式
5. 枚举式
下面分别展示这五种写法(详细内容可以参考博主的《singleton模式四种线程安全的实现》和《如何防止单例模式被JAVA反射攻击》)
Jdk中的单例模式:
java.lang.Runtime#getRuntime()
参考资料
1. 《singleton模式四种线程安全的实现》
2. 《如何防止单例模式被JAVA反射攻击》
3. 《JAVA序列化 》
4. 《Java枚举类型enum》
5. 《Effective Java(Second Edition)》Joshua Bloch.
6. 《细数JDK里的设计模式》
转载自:http://blog.csdn.net/u013256816/article/details/50966882
单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
适用性:当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
单例模式有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里的设计模式》
转载自:http://blog.csdn.net/u013256816/article/details/50966882
相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- Ruby设计模式编程之适配器模式实战攻略
- 实例讲解Ruby使用设计模式中的装饰器模式的方法
- 设计模式中的模板方法模式在Ruby中的应用实例两则
- Ruby设计模式编程中对外观模式的应用实例分析
- 实例解析Ruby设计模式编程中Strategy策略模式的使用
- Ruby中使用设计模式中的简单工厂模式和工厂方法模式
- Ruby使用设计模式中的代理模式与装饰模式的代码实例
- 详解组合模式的结构及其在Ruby设计模式编程中的运用
- C#编程中使用设计模式中的原型模式的实例讲解
- 使用设计模式中的工厂方法模式进行C#编程的示例讲解
- 实例解析C#设计模式编程中简单工厂模式的使用
- 详解C#设计模式编程中生成器模式的使用
- 深入解析C#设计模式编程中对建造者模式的运用