单例模式的几种创建方式

    科技2022-07-13  132

    单例模式

    创建方式

    饿汉方式:指全局的单例实例在类装载时构建懒汉方式:指全局的单例实例在第一次被使用时构建

    不管是那种创建方式,它们通常都存在下面几点相似处:

    单例类必须要有一个 private 访问级别的构造函数,只有这样,才能确保单例不会在系统中的其他代码内被实例化;instance 成员变量和 uniqueInstance 方法必须是 static 的。

    饿汉模式(线程安全)

    public class Singleton { //在静态初始化器中创建单例实例,这段代码保证了线程安全 private static Singleton uniqueInstance = new Singleton(); //Singleton类只有一个构造方法并且是被private修饰的,所以用户无法通过new方法创建该对象实例 private Singleton(){} public static Singleton getInstance(){ return uniqueInstance; } }

    懒汉模式

    线程不安全

    public class Singleton { private static Singleton uniqueInstance; private Singleton () {} //没有加入synchronized关键字的版本是线程不安全的 public static Singleton getInstance() { //判断当前单例是否已经存在,若存在则返回,不存在则再建立单例 if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; } }

    线程安全

    给getInstance方法加上syncronized public class Singleton { private static Singleton uniqueInstance; private Singleton (){ } // 加入synchronized关键字的版本是线程安全的 public static synchronized Singleton getInstance() { if (instance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; } }

    双重校验锁版本

    实例变量为volatile public class Singleton { // volatile保证,当uniqueInstance变量被初始化成Singleton实例时,多个线程可以正确处理 uniqueInstance变量 private volatile static Singleton uniqueInstance; private Singleton() { } public static Singleton getInstance() { //检查实例,如果不存在,就进入同步代码块 if (uniqueInstance == null) { //只有第一次才彻底执行这里的代码 synchronized(Singleton.class) { //进入同步代码块后,再检查一次,如果仍是null,才创建实例 if (uniqueInstance == null) { uniqueInstance = new Singleton(); } } } return uniqueInstance; } }

    懒汉式(登记式/静态内部类方式)

    只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance(只有第一次使用这个单例的实例的时候才加载,同时不会有线程安全问题)。

    public class Singleton { private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton (){} public static final Singleton getInstance() { return SingletonHolder.INSTANCE; } }

    饿汉式(枚举方式)

    使用枚举来实现单实例控制会更加简洁,而且无偿地提供了序列化机制,并由JVM从根本上提供保障,绝对防止多次实例化,是更简洁、高效、安全的实现单例的方式。

    public enum Singleton { //定义一个枚举的元素,它就是 Singleton 的一个实例 INSTANCE; public void doSomeThing() { System.out.println("枚举方法实现单例"); } } public class ESTest { public static void main(String[] args) { Singleton singleton = Singleton.INSTANCE; singleton.doSomeThing();//output:枚举方法实现单例 } }
    Processed: 0.014, SQL: 8