源码 : 设计模式之单例模式的5种实现

2020-07-13 10:25:24 浏览数 (1)

方式一:饿汉式

代码语言:txt复制
package cn.relaxheart.designModel.singleton;

/**
 *
 * @Date: 2019-6-1 0001 15:49
 * @Description: 单例实现方式一:饿汉式单例
 *
 * 1. 饿汉式单例在类加载初始化时就创建了一个静态的对象供外部使用,除非系统重启,否则这个对象不会改变。【线程安全】
 *
 * 2. 私有构造,限制外部类实例化该对象 (事实上通过反射是可以实例化构造方法为私有的类的,那基本上会使所有的Java单例实例失效.)
 * 3. 唯一实例只能通过getInstance()方法获取
 *
 */
public class SingletonModel1 {

    // 1. 私有构造
    private SingletonModel1(){}

    // 2. 私有静态全局变量
    private static SingletonModel1 singletonModel1 = new SingletonModel1();

    // 3. 公有静态工厂方法
    public static SingletonModel1 getInstance(){
        return singletonModel1;
    }
}
方式二:懒汉式

代码语言:txt复制
package cn.relaxheart.designModel.singleton;

/**
 *
 * @Date: 2019-6-1 0001 15:55
 * @Description: 单例模式实现方式二:懒汉式(延迟加载)
 *
 * 1. 该方式虽然通过延迟加载实现了单例,但是在多线程环境在会产生多个SingletonModel2实例【非线程安全】
 */

public class SingletonModel2 {

    // 1. 私有构造
    private SingletonModel2(){}

    // 2. 私有静态全局为初始化实例变量
    private static SingletonModel2 singletonModel2 = null;

    public static SingletonModel2 getInstance(){
        if (singletonModel2 == null){
            singletonModel2 = new SingletonModel2();
        }
        return singletonModel2;
    }
}

线程安全问题优化:

代码语言:txt复制
package cn.relaxheart.designModel.singleton;

/**
 *
 * @Date: 2019-6-1 0001 15:58
 * @Description: 使用synchronized同步锁 对懒汉式单例优化
 *
 * 1. 方法上加synchroinzed,或者使用同步代码块加同步锁,此方法虽然解决了线程安全问题,但是效率低下。当一个线程想要获取实例,
 * 还需要等待上一个线程释放锁。
 */

public class SingletonModel21 {

    // 1. 私有构造
    private SingletonModel21(){}

    // 2. 私有静态未初始化实例
    private static SingletonModel21 singletonModel21 = null;

    public static SingletonModel21 getInstance(){

        // 等同于 synchronized public static SingletonModel21 getInstance()
        synchronized (SingletonModel21.class){
            if (singletonModel21 == null){
                singletonModel21 = new SingletonModel21();
            }
        }

        return singletonModel21;
    }
}

优化方法前加同步锁影响效率的实现

代码语言:txt复制
package cn.relaxheart.designModel.singleton;

/**
 * 
 * @Date: 2019-6-1 0001 16:03
 * @Description: 延迟加载同步锁优化
 *
 * 1. 使用双重检查锁,可以避免整个方法加锁,只对需要加锁的代码块加锁,可提高效率。
 */

public class SingletonModel22 {

    // 1. 私有构造
    private SingletonModel22(){}

    private static SingletonModel22 singletonModel22 = null;

    public static SingletonModel22 getInstance(){
        if (singletonModel22 == null){
            synchronized (SingletonModel22.class){
                if (singletonModel22 == null){
                    singletonModel22 = new SingletonModel22();
                }
            }
        }

        return singletonModel22;
    }
}
方式三:静态内部类

代码语言:txt复制
package cn.relaxheart.designModel.singleton;

/**
 * @Author: 王琦 <QQ.Eamil>1124602935@qq.com</QQ.Eamil>
 * @Date: 2019-6-1 0001 16:06
 * @Description: 单例模式实现方式三:静态内部类
 *
 * 1. 静态内部类虽然保证了多线程环境下的线程安全性,但是在遇到序列化对象时,默认方式运行结果实际上是多例的。
 */

public class Singleton3 {

    private static class Singleton3Clss{
        private static Singleton3 singleton3 = new Singleton3();
    }

    public static Singleton3 getInstance(){
        return Singleton3Clss.singleton3;
    }
}
方式四:静态代码块

代码语言:txt复制
package cn.relaxheart.designModel.singleton;

/**
 * 
 * @Date: 2019-6-1 0001 16:19
 * @Description: 单例实现方式:静态代码块
 */

public class Singleton4 {

    // 1. 私有构造
    private Singleton4(){}

    private static Singleton4 singleton4 = null;

    static {
        singleton4  = new Singleton4();
    }

    public static Singleton4 getInstance(){
        return singleton4;
    }
}
方式五:内部枚举类

代码语言:txt复制
public class SingletonFactory {
    // 内部枚举类
    private enum EnmuSingleton{
        Singleton;
        private Singleton5 singleton;
        //枚举类的构造方法在类加载是被实例化 
        private EnmuSingleton(){
            singleton = new Singleton5();
        }
        public Singleton5 getInstance(){
            return singleton;
        }
    }
    public static Singleton5 getInstance() {
        return EnmuSingleton.Singleton.getInstance();
    }
}
class Singleton5{
    public Singleton5(){}
}

0 人点赞