第一站,单身狗的单例模式

单例模式是最常用到的设计模式之一,介绍单例模式的书籍一般都会提到 饿汉式  懒汉式 这两种实现方式。


 

先来两个线程安全可用的饿汉式:

public class SingleObject {
 
   //利用static特性,创建一个实例
   private static SingleObject instance = new SingleObject();
 
   //让构造函数私有化
   private SingleObject(){}
 
   //对外暴露获取实例的方法
   public static SingleObject getInstance(){
      return instance;
   }
 
   public void showMessage(){
      System.out.println("this is a singletonDemo!");
   }
}
public class Singleton {
  //同上边的一样,改为静态代码块制造实例
    private static Singleton instance;

    static {
        instance = new Singleton();
    }

    private Singleton() {}

    public static Singleton getInstance() {
        return instance;
    }
}

 

再来个单线程可用线程不安全的懒汉式:

public class Singleton {

    private static Singleton singleton;

    private Singleton() {}

    public static Singleton getInstance() {
      
if (singleton == null) {//多线程环境下,前边线程此处判断没执行完,后边线程跟进来,会导致制造多个实例,失去单例模式的意义 singleton = new Singleton(); } return singleton; } }

上边懒汉式线程不安全,那就改造一下,为懒汉式加个锁可以用但是不推荐使用

public class Singleton {

    private static Singleton singleton;

    private Singleton() {}
  //效率太低了,每个线程在想获得类的实例时候,执行getInstance()方法都要进行同步。
    public static synchronized Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}

接下来演示一个错误的不可用的懒汉式改造,目的就是为了线程安全和效率

public class Singleton {

    private static Singleton singleton;

    private Singleton() {}

    public static Singleton getInstance() {
        if (singleton == null) { 
       //多线程判断为空都进来了,在这儿排着队new实例,好比自欺欺人。
synchronized (Singleton.class) { singleton = new Singleton(); } } return singleton; } }

抛砖引玉,引出来的双检索模式推荐使用

public class Singleton {
  //关键字valatile:解决可见性,防止重排序,无法保证原子性。
    private static volatile Singleton singleton;

    private Singleton() {}

    public static Singleton getInstance() {
        if (singleton == null) {//valatile的可见性,此处表现为提高效率
            synchronized (Singleton.class) {
                if (singleton == null) { //valatile的可见性,保证此处判断实时性,线程安全性,只会创建一次实例。
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

比饿汉式多了懒加载特性的静态内部类创建单例模式:推荐使用

public class Singleton {

    private Singleton() {}
  //静态内部类不同于静态成员和代码块,不会在主类加载的时候立即加载,而是在调用的时候第一次加载,即懒加载
    private static class SingletonInstance {
     //TODO 内外部类的关系
private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonInstance.INSTANCE; } }

最后来一个高大上的根据枚举特性实现单例模式,就睡觉啦!

public enum Singleton {
    INSTANCE;
    public void whateverMethod() {
        system.out.println("枚举模式好,但是用的少。我最喜欢的");
    }
  public static void main(String[] args) {
SingletonEnum.INSTANCE.whateverMethod();
  }

}

第一站,单身狗的单例模式

 

 



第一站,单身狗的单例模式

上一篇:浏览器中的事件循环


下一篇:dynamic 365 配置默认登录应用程序