设计模式--单例模式

简介

创建型模式,这种模式只涉及一个单独的类,它负责创建自己的对象,该类也确保只创建单个对象。

特点
类构造器私有
持有自己类型的属性
对外提供获取实例的静态方法

分类

常用分类有五种:
1、懒汉式
懒汉式,顾名思义就是实例在用到的时候才去创建,“比较懒”,用的时候才去检查有没有实例,如果有则返回,没有则新建。有线程安全和线程不安全两种写法,区别就是synchronized关键字。
2、饿汉式
饿汉式,从名字上也很好理解,就是“比较勤”,实例在初始化的时候就已经建好了,不管你有没有用到,都先建好了再说。好处是没有线程安全的问题,坏处是浪费内存空间。
3、双检锁
双检锁,又叫双重校验锁,综合了懒汉式和饿汉式两者的优缺点整合而成。看上面代码实现中,特点是在synchronized关键字内外都加了一层
if 条件判断,这样既保证了线程安全,又比直接上锁提高了执行效率,还节省了内存空间。
4、静态内部类
静态内部类的方式效果类似双检锁,但实现更简单。但这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用。
5、枚举
枚举的方式是比较少见的一种实现方式,但是看上面的代码实现,却更简洁清晰。并且她还自动支持序列化机制,绝对防止多次实例化。

简单示例

public class LazySingleton {

    private static LazySingleton lazySingleton;
    private LazySingleton(){};
    public static LazySingleton getInstance(){
        if (lazySingleton == null) {
            lazySingleton  = new LazySingleton();
        }
        return lazySingleton;
    }
}
public class HungrySingleton {
   
    private static final HungrySingleton hungrySingleton = new HungrySingleton();
    private HungrySingleton(){};
    public static HungrySingleton getInstance(){
        return hungrySingleton;
    }
}

public class DoubleCheck {
    private volatile static DoubleCheck instance;
    private DoubleCheck(){};

    public static DoubleCheck getInstance(){
        if (instance == null) {
            //加锁 防止多线程 生成多个实例对象
            synchronized (DoubleCheck.class){
                if (instance == null) {
                    return new DoubleCheck();
                }
            }
        }
        return instance;
    }
}

public class InnerStaticSingleton {

    public InnerStaticSingleton(){
        if (InnerClass.innerStaticSingleton != null) {
            throw new RuntimeException("不允许反射创建实例");
        }
    }
    public static InnerStaticSingleton getInstance(){
        return InnerClass.innerStaticSingleton;
    }

    private static class InnerClass{
        private static final InnerStaticSingleton innerStaticSingleton = new InnerStaticSingleton();
    }
}

public class EnumSingleton {
    private EnumSingleton(){};

    public static EnumSingleton getInstance(){
        return Enums.INSTANCE.getInstance();
    }
    private enum Enums{
        INSTANCE;
        private EnumSingleton enumSingleton;
        Enums(){
            enumSingleton = new EnumSingleton();
        }
        public EnumSingleton getInstance(){
            return enumSingleton;
        }
    }
}


main:

public class Main {
    public static void main(String[] args) {
        HungrySingleton h1 = HungrySingleton.getInstance();
        HungrySingleton h2 = HungrySingleton.getInstance();

        LazySingleton l1 = LazySingleton.getInstance();
        LazySingleton l2 = LazySingleton.getInstance();

        InnerStaticSingleton i1 = InnerStaticSingleton.getInstance();
        InnerStaticSingleton i2 = InnerStaticSingleton.getInstance();

        DoubleCheck d1 = DoubleCheck.getInstance();
        DoubleCheck d2 = DoubleCheck.getInstance();

        EnumSingleton e1 =  EnumSingleton.getInstance();
        EnumSingleton e2 = EnumSingleton.getInstance();

        System.out.println("h1 :" + h1 + "===== h2 : " + h2  + "-----" + (h1.equals(h2)));
        System.out.println("l1 :" + l1 + "===== l2 : " + l2  + "-----" + (l1.equals(l2)));
        System.out.println("i1 :" + i1 + "===== i2 : " + i2  + "-----" + (i1.equals(i2)));
        System.out.println("d1 :" + d1 + "===== d2 : " + d2  + "-----" + (d1.equals(d2)));
        System.out.println("e1 :" + e1 + "===== e2 : " + e2  + "-----" + (e1.equals(e2)));
    }
}
h1 :com.demo.designpattern.singleton.HungrySingleton@3cd1a2f1===== h2 : com.demo.designpattern.singleton.HungrySingleton@3cd1a2f1-----true
l1 :com.demo.designpattern.singleton.LazySingleton@2f0e140b===== l2 : com.demo.designpattern.singleton.LazySingleton@2f0e140b-----true
i1 :com.demo.designpattern.singleton.InnerStaticSingleton@7440e464===== i2 : com.demo.designpattern.singleton.InnerStaticSingleton@7440e464-----true
d1 :com.demo.designpattern.singleton.DoubleCheck@49476842===== d2 : com.demo.designpattern.singleton.DoubleCheck@49476842-----true
e1 :com.demo.designpattern.singleton.EnumSingleton@78308db1===== e2 : com.demo.designpattern.singleton.EnumSingleton@78308db1-----true
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值