Java设计模式(一) 之 详解单例模式
2015-07-23 17:55
387 查看
1.前言
单例模式可能是设计模式中相对比较简单的而且在工作中应用最频繁的设计模式了,例如系统配置文件的读取工具类要求得保证其实例唯一性。再比如在需要调用计算机底层时,需要一个Java来使用JNI来与其他语言进行交互,此时可能需要保证Java类的实例是唯一的。
那么在编写单例模式时,需要考虑哪些问题呢?
2.简单实现:
常规单例模式实现的原则:
1.实例变量私有化;
2.构造方法私有化;
3.提供静态的基于类的方法放回实例;
遵循这三个原则,可以在最单纯的环境下设计出单例模式。单例模式的最简单实现就是懒汉式和饿汉式,如下:
饿汉式:
特点:线程安全,在类加载初期即完成了对类的实例化;
懒汉式:
特点:线程不安全,在首次获取实例时完成对类的实例化;
3.双重加锁:
当然,在进行单例模式的设计时,也需要考虑并发的问题,比如饿汉式的设计,如上简单时,并发情况下就会存在问题,可能会产生多个实例;
双重加锁机制:
特点:可以防止在多线程环境由于并发导致的多个实例的问题;
4.enum枚举实现单例:
当然即使使用了以上何种方式,在反射和字节码技术面前,还是会毫无抵抗之力,依然可以轻松的生产出多个实例。在JDK1.5中引入了enum枚举类型,依靠枚举类型亦可以实现单利模式,而且可以解决并发和发射层面导致的多个实例的问题。
enum单例实现:
特点:基于enum实现的单例模式,完全可以防止反射的多实例化。
总结:无论何种单例模式的实现,目的都是一样的,在运行环境内产生唯一的实例。但是具体采用哪种单例模式的实现,需要根据场景具体而定。
本人强烈推荐enum实现单例模式,因为enum防止了各种层面对于类的实例化。当然,如果确定运行环境是单线程,那么完全可以使用最简单的饿汉式或者懒汉式实现,因场景而定。
单例模式可能是设计模式中相对比较简单的而且在工作中应用最频繁的设计模式了,例如系统配置文件的读取工具类要求得保证其实例唯一性。再比如在需要调用计算机底层时,需要一个Java来使用JNI来与其他语言进行交互,此时可能需要保证Java类的实例是唯一的。
那么在编写单例模式时,需要考虑哪些问题呢?
2.简单实现:
常规单例模式实现的原则:
1.实例变量私有化;
2.构造方法私有化;
3.提供静态的基于类的方法放回实例;
遵循这三个原则,可以在最单纯的环境下设计出单例模式。单例模式的最简单实现就是懒汉式和饿汉式,如下:
饿汉式:
public class SingleTon { public static SingleTon instance = new SingleTon(); private SingleTon(){} public static SingleTon getInstance(){ return instance; } }
特点:线程安全,在类加载初期即完成了对类的实例化;
懒汉式:
public class SingleTon { public static SingleTon instance = null; private SingleTon(){} public static SingleTon getInstance(){ if(null == instance) instance = new SingleTon(); return instance; }
特点:线程不安全,在首次获取实例时完成对类的实例化;
3.双重加锁:
当然,在进行单例模式的设计时,也需要考虑并发的问题,比如饿汉式的设计,如上简单时,并发情况下就会存在问题,可能会产生多个实例;
双重加锁机制:
public class SingleTon { public static SingleTon instance = null; // .. 内部定义对象锁,当并发条件下,需要竞争syncLock的锁。 private static final Object syncLock = new Object(); private SingleTon(){} public static SingleTon getInstance(){ if(null == instance){ // .. 竞争syncLock锁的线程才可以执行代码块内容,其他线程等待 synchronized (syncLock) { if (null == instance) { instance = new SingleTon(); } } } return instance; }
特点:可以防止在多线程环境由于并发导致的多个实例的问题;
4.enum枚举实现单例:
当然即使使用了以上何种方式,在反射和字节码技术面前,还是会毫无抵抗之力,依然可以轻松的生产出多个实例。在JDK1.5中引入了enum枚举类型,依靠枚举类型亦可以实现单利模式,而且可以解决并发和发射层面导致的多个实例的问题。
enum单例实现:
public enum SingleTon { insatnce; private SingleTon(){} }
特点:基于enum实现的单例模式,完全可以防止反射的多实例化。
总结:无论何种单例模式的实现,目的都是一样的,在运行环境内产生唯一的实例。但是具体采用哪种单例模式的实现,需要根据场景具体而定。
本人强烈推荐enum实现单例模式,因为enum防止了各种层面对于类的实例化。当然,如果确定运行环境是单线程,那么完全可以使用最简单的饿汉式或者懒汉式实现,因场景而定。
相关文章推荐
- 要慎用mysql的enum字段的原因
- 枚举的用法详细总结
- php设计模式之单例模式实例分析
- c#入门之枚举和结构体使用详解(控制台接收字符串以相反的方向输出)
- 理解C#中的枚举(简明易懂)
- C#枚举中的位运算权限分配浅谈
- C#设计模式之单例模式实例讲解
- JS模式之单例模式基本用法
- 深入理解JavaScript系列(25):设计模式之单例模式详解
- C++基础入门教程(四):枚举和指针
- FileShare枚举的使用小结(文件读写锁)
- Java枚举类用法实例
- c++ 尽量不要使用#define 而是用const、enum、inline替换。
- 枚举窗口句柄后关闭所有窗口示例
- mysql之set与enum的介绍
- javascript模拟枚举的简单实例
- 深入剖析JavaScript中的枚举功能
- Java单例模式、饥饿模式代码实例
- Python中模拟enum枚举类型的5种方法分享
- Android源码学习之单例模式应用及优点介绍