设计模式之单例模式(饿汉式、懒汉式)

单例模式

什么是单例模式

单例模式是指:保证一个类仅有一个实例,并提供一个访问它的全局访问点(即public的访问方法)

如何实现单例模式

让类自身负责保存它的唯一实例,这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的公共方法。

具体实现:

  1. 私有化构造方法
  2. 创建private satic的对象实例
  3. 提供唯一的public static的访问本类实例的访问方法

单例模式类型

  1. 饿汉式
    优点:
    天生线程安全,因为在类被加载的时候,实例就已经创建了,不存在多线程调用的时候重复创建问题。
    缺点:
    类加载的时候就被实例化,如果用不到,浪费资源。大型项目一般不会使用饿汉式,因为会加长项目启动时间。
/**
 * @author 小白学长
 * @create 2020-07-27 22:07
 */
public class Singleton {
    // 私有化构造方法
    private Singleton(){

    }
    // 创建私有化静态实例
    private static Singleton singleton = new Singleton();
    // 提供public全局访问方法
    public static Singleton getInstance(){
        return singleton;
    }
}

2.懒汉式(也成为延迟加载模式)

优点:
延迟加载,降低大型项目的启动时间,避免资源浪费。
缺点:
线程不安全,需要做特殊处理。

/**
 * @author 小白学长
 * @create 2020-07-27 22:13
 */
public class Singletion {
    // 私有化构造方法
    private Singletion(){

    }
    // 私有化静态对象
    private static Singletion singletion;
    //全局访问点
    public static Singletion getInstance(){
        if (singletion == null){
            singletion = new Singletion();
        }
        return singletion;
    }
}

为什么线程不安全?
原因在于调用 getInstance方法时,如果是多个线程调用,判断是否为null时,可能此时singletion还没有创建,多个线程都走进了if里面,从而创建了多个对象

线程安全写法

/**
 * @author 小白学长
 * @create 2020-07-27 22:19
 */
public class Singleton1 {
    // 私有化构造方法
    private Singleton1(){

    }
    // 私有化静态实例  volatile有两个作用 1。保证修饰的变量对其他线程可见 2.禁止指令重排序
    private static volatile Singleton1 singleton1;
    // 全局静态方法
    public static Singleton1 getInstance(){
        // 第一次判断,该对象是否存在
        if (singleton1 == null){
            // 加锁
            synchronized (Singletion1.class){
                // 再次判断,避免第一个加锁的线程创建实例后,其他线程加锁再次创建实例
                if (singleton1 == null){
                    singleton1 = new Singleton1();
                }
            }
        }
        return singleton1;
    }
}

另外还有一种静态内部类形式,很好理解,就不多赘述了

public class Singleton2 { 
    private Singleton2(){
    }
    public static Singleton2 getInstance(){  
        return Inner.instance;  
    }  
    private static class Inner {  
        private static final Singleton2 singleton2 = new Singleton2();  
    }  
} 

你可能感兴趣的:(设计模式)