单例模式

Posted xingrui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式相关的知识,希望对你有一定的参考价值。

多种实现方式

  • 饿汉式
  • 懒汉式 (DCL必会)
  • 枚举 (自己用推荐)
    在多种实现方式下,需要注意多线程环境下线程安全问题

首先,考虑如何确保单例?

1、如果在外部所有人都可以访问单例类的构造器,那就可以直接创建对象,所以构造器私有化。
2、构造器私有化了以后,只有自己可以创建对象,因此需要对外暴露一个方法getInstance(静态方法?原因外部没有实例,没有办法调用对象方法),让其他人获取对象。
3、由于全局唯一,不能创建多次,所以第一次创建完,需要保存到属性中,当下一次获取对象时,先去判断有没有该实例,有则直接返回该实例对象;并且由于getInstance
要访问该属性,所以属性加static进行修饰。原因:静态方法不能访问非静态属性,但是非静态方法可以访问静态属性。有类不一定有对象,有对象时,一定有类。

饿汉式(加载类时直接创建,懒汉式使用时才会创建)

线程安全,原因:类加载时属性初始化,且初始化一次。

public class Singleton {  
   private static Singleton 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 instance;  
   private Singleton (){}  
   public static synchronized Singleton getInstance() {  
   if (instance == null) {  
       instance = new Singleton();  
   }  
   return instance;  
   }  
}

//DCL 双检锁
public class Singleton {
    // volatile 防止指令重排,
    private volatile static Singleton singleton;

    private Singleton() {
    }

    // DCL  双检锁
    public static Singleton getSingleton(){
        if(singleton == null){
            synchronized (Singleton.class){
                if (singleton == null){
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

// 枚举方式
public enum Singleton {  
   INSTANCE; 
}




以上是关于单例模式的主要内容,如果未能解决你的问题,请参考以下文章

常用代码片段

性能比较好的单例写法

片段作为 Android 中的单例

单例片段或保存网页视图状态

你熟悉的设计模式都有哪些?写出单例模式的实现代码

单例模式以及静态代码块