/ Java / 198浏览

单例模式

单例模式的五种创建方法

单例模式确保只有一个对象,避免重复创建对象

1.饿汉模式(the singleton instance is early created at complie time) 提前创建了对象

package top.freeme.my;

/**
 * @author Administrator
 * 饿汉式
 */
public class SingleTon {

    private static SingleTon singleTon = new SingleTon();
    private SingleTon() {
    }

    public static SingleTon getInstance(){

        return singleTon;
    }

以空间换时间,故不存在线程安全问题。
由于private static SingleTon singleTon = new SingleTon();语句被static修饰,这个Singleton对象在一开始就被创建了,是线程安全的

2.懒汉式(the singleton instance is lazily created at runtime) 后面在创建对象

package top.freeme.my;

/**
 * @author Administrator
 * 饿汉式
 */
public class SingleTon2 {

    private static SingleTon2 singleTon = null;
    private SingleTon2() {
    }

    public static SingleTon2 getInstance(){

        if (singleTon==null){
            singleTon = new SingleTon2();
        }
        return singleTon;

    }
}

懒汉模式在方法被调用后才创建对象,以时间换空间,在多线程环境下存在风险。

3.双重锁懒汉模式

package top.freeme.my;

/**
 * @author Administrator
 * 双检锁
 */
public class SingleTon3 {

//-- 这里需要加volatile关键字,要不然线程不安全
    private static volatile SingleTon3 singleTon = null;
    private SingleTon3() {
    }

    public static SingleTon3 getInstance(){
        if (singleTon==null){
            synchronized (SingleTon3.class){
                if (singleTon==null){
                    singleTon = new SingleTon3();
                }
            }
        }

        return singleTon;

    }
}

jvm存在乱序执行,因此需要加volatile关键字确保线程安全
具体原理参考
https://blog.csdn.net/mnb65482/article/details/80458571
4.静态内部类模式 推荐使用

package top.freeme.my;

/**
 * @author Administrator
 * 双检锁
 */
public class SingleTon4 {

    private static volatile SingleTon4 singleTon = null;
    private SingleTon4() {}
    private static class Inner{
        private static final SingleTon4 singleTon4= new SingleTon4();
    }
    public SingleTon4 getInstance(){
        return Inner.singleTon4;
    }

}

线程安全的,同时也延迟了单例的实例化。但是不能传递参数

5.枚举

package top.freeme.my;

/**
 * @author Administrator
 * 单例模式枚举
 */
public enum SingleTon5 {;

    private static SingleTon singleTon5 = new SingleTon();

    public static void main(String[] args) {

        SingleTon singleTon5 = SingleTon5.singleTon5;
    }

}

参考链接
https://blog.csdn.net/mnb65482/article/details/80458571