单例模式

来源:互联网 发布:mac 装双系统 怎么备份 编辑:程序博客网 时间:2024/06/03 12:33

单例模式是在学习Java设计模式过程中接触最多的一个模式。单例模式的写法有好几种形式,虽然形式各异,但目的都是为了保证 一个类仅有一个实例,并提供一个访问它的全局入口(getInstance())。

饿汉式

public class Singleton {    private static Singleton instance = new Singleton();    //构造函数私有化 ,确保外部无法直接实例化    private Singleton() {};    public Singleton getInstance() {          return instance;    }}

懒汉式(添加了“双检锁”,解决数据同步问题)

public class Singleton {     private static Singleton instance;     private Singleton() {};     //添加“双检锁”。解决数据同步问题     public Singleton getInstance() {          if(instance == null) {               synchronized (Singleton.class) {//synchoronized关键字也是可以加到方法上,但是这样效率太低了                    if(instance == null) {                         instance = new Singleton();                    }               }          }          return instance;     }}

静态内部类中创建单例类实例

//简单实现public class Singleton {       private Singleton() {};     private static class SingletonHolder {          private static final Singleton INSTANCE = new Singleton();     }     public Singleton getInstance() {          return SingleHolder.INSTANCE;     }}

上面这种实现单例的方式,同样无法避免通过Java的反射机制调用私有的构造函数创建出第二个单例类的实例。为了避免这个问题,我们可以去修改构造函数,使它在被要求创建第二个实例时抛出异常。

//避免“反射”机制攻击public class Singleton {     private static boolean isCreated;         // 如果二次调用构造函数就抛出一个异常     private Singleton() {          synchronized(Singleton.class) {               if(isCreated) {                    throw new RuntimeException("单例模式被攻击了!");               }else {                    isCreated = true;               }          }     }     private static class SingletonHolder {          private static final Singleton INSTANCE = new Singleton();     }     public Singleton getInstance() {          return SingletonHolder.INSTANCE;     }}

枚举实现单例

public enum Singleton {     INSTANCE;}

单元素的枚举类型是目前实现单例模式的最佳实践,即可以防止反射攻击,可以防止序列化破坏单例模式。

参考文章
如何防止单例模式被 JAVA 反射攻击
singleton模式四种线程安全的实现

0 0
原创粉丝点击