你的位置:首页 > ASP.net教程

[ASP.net教程]Java设计模式之单例模式(Singleton)


前言:

     在总结okHttp的时候,为了管理网络请求使用到了单例模式,晚上实在没啥状态了,静下心来学习总结一下使用频率最高的设计模式单例模式。

 单例模式:

       单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

单例特点:

  • 单例类只能有一个实例。
  • 单例类必须自己创建自己的唯一实例。
  • 单例类必须给所有其他对象提供这一实例。

单例分类:

     1).懒汉单例

    (1)非线程安全实现

public class Singleton {     private Singleton(){     }     private static Singleton instance;     public static Singleton getInstance(){       if(instance == null){         instance = new Singleton();       }   return instance;     }   } 

  (2)线程安全实现方式一  方法加同步 这种实现方式效率不高

public class Singleton {      private Singleton(){     }     private static Singleton instance;     public static synchronized Singleton getInstance(){       if(instance == null){         instance = new Singleton();       }    return instance;      }   }

 (3.)线程安全实现方式二 双重检查锁定

public class Singleton{  private static Singleton single;  //声明静态的单例对象的变量  private Singleton(){}  //私有构造方法   public static Singleton getSingle(){  //外部通过此方法可以获取对象    if(single == null){       synchronized (Singleton.class) {  //保证了同一时间只能只能有一个对象访问此同步块          if(single == null){           single = new Singleton();           }       }   }    return single;  //返回创建好的对象   } } 

2.)饿汉式单例类

      饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。

public class Singleton {   private Singleton(){   }   private final static Singleton instance = new Singleton();   private static Singleton getInstance(){     return instance;   } } 

 

3.)内部类式单例类

内部类式中,实现了延迟加载,只有我们调用了getInstance(),才会创建唯一的实例到内存中.并且也解决了懒汉式中多线程的问题.解决的方式是利用了Classloader的特性,既实现了线程安全,又避免了同步带来的性能影响。

public class Singleton{       private Singleton(){      }     private class SingletonHoledr(){       private static Singleton instance = new Singleton();     }     private static Singleton getInstance(){       return SingletonHoledr.instance;     }   } 

4.)枚举类单例

《Effective Java》作者推荐使用的方法,优点:不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象

public enum Singleton {  /**   * 定义一个枚举的元素,它就代表了Singleton的一个实例。   */    uniqueInstance;    /**   * 单例可以有自己的操作   */  public void doSomeThing(){    //功能处理  }}

5.)懒汉和饿汉区别

(1)初始化角度

     饿汉就是类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了,而懒汉比较懒,只有当调用getInstance的时候,才回去初始化这个单例

(2)线程安全角度

     饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题,懒汉式本身是非线程安全的,需要自己实现线程安全的方法。