关于设计模式:『设计模式』单例模式

2次阅读

共计 1969 个字符,预计需要花费 5 分钟才能阅读完成。

GitHub 源码分享

微信搜寻:码农 StayUp

主页地址:https://gozhuyinglong.github.io

源码分享:https://github.com/gozhuyinglong/blog-demos

1. 单例模式

单例模式(Singleton Pattern)是一种简略的对象创立型模式。该模式保障一个类仅有一个实例,并提供一个拜访它的全局拜访点。

所以要实现单例模式,要做到以下几点:

  • 将构造方法私有化,杜绝应用结构器创立实例。
  • 须要本身创立惟一的一个实例,并提供一个全局拜访入口

2. 单例模式的几种实现

对于单例模式有以下 5 种实现。

2.1. 懒汉式

该形式是应用 synchronized 关键字进行加锁,保障了线程安全性。
长处:在第一次调用才初始化,防止了内存节约。
毛病:对获取实例办法加锁,大大降低了并发效率。

因为加了锁,对性能影响较大,不举荐应用。

public class SingletonLazy {

    /**
     * 公有实例
     */
    private static SingletonLazy instance;

    /**
     * 公有构造方法
     */
    private SingletonLazy() {}

    /**
     * 惟一公开获取实例的办法(动态工厂办法),该办法应用 synchronized 加锁,来保障线程安全性
     *
     * @return
     */
    public static synchronized SingletonLazy getInstance() {if (instance == null) {instance = new SingletonLazy();
        }
        return instance;
    }

}

2.2 饿汉式

饿汉式是利用类加载机制来防止了多线程的同步问题,所以是线程平安的。
长处:未加锁,执行效率高。
毛病:类加载时就初始化实例,造成内存节约。

如果对内存要求不高的状况,还是比拟举荐应用这种形式。

public class SingletonEager {

    /**
     * 公有实例,动态变量会在类加载的时候初始化,是线程平安的
     */
    private static final SingletonEager instance = new SingletonEager();

    /**
     * 公有构造方法
     */
    private SingletonEager() {}

    /**
     * 惟一公开获取实例的办法(动态工厂办法)*
     * @return
     */
    public static SingletonEager getInstance() {return instance;}
}

2.3 双重校验锁

利用了 volatile 修饰符的线程可见性(被一个线程批改后,其余线程立刻可见),即保障了懒加载,又保障了高性能,所以举荐应用。

public class SingletonDCL {

    /**
     * 公有实例,volatile 润饰的变量是具备可见性的(即被一个线程批改后,其余线程立刻可见)*/
    private volatile static SingletonDCL instance;

    /**
     * 公有构造方法
     */
    private SingletonDCL() {}

    /**
     * 惟一公开获取实例的办法(动态工厂办法)*
     * @return
     */
    public static SingletonDCL getInstance() {if (instance == null) {synchronized (SingletonDCL.class) {if (instance == null) {instance = new SingletonDCL();
                }
            }
        }
        return instance;
    }
}

2.4 动态外部类

该模式利用了动态外部类提早初始化的个性,来达到与双重校验锁形式一样的性能。因为须要借助辅助类,并不罕用。

public class SingletonInnerClass {

    /**
     * 公有构造方法
     */
    private SingletonInnerClass() {}

    /**
     * 惟一公开获取实例的办法(动态工厂办法)*
     * @return
     */
    public static SingletonInnerClass getInstance() {return LazyHolder.INSTANCE;}

    /**
     * 公有动态外部类
     */
    private static class LazyHolder {private static final SingletonInnerClass INSTANCE = new SingletonInnerClass();
    }
}

2.5 枚举类

该形式利用了枚举类的个性,不仅能防止线程同步问题,还避免反序列化从新创立新的对象。这种形式是 Effective Java 作者 Josh Bloch 提倡的形式。

但因为这种编码方式还不能适应,所以理论工作中很少应用。

public enum SingletonEnum {

    INSTANCE;

    public void method() {System.out.println("枚举类中定义方法!");
    }

}

正文完
 0