1.单例模式

啥是单例?单例能干啥啊?小伙伴是不是跟我有一样的疑惑

 你看懂了吗,说实话我有点点懵,可能脑子不太好用

又是一顿乱搜,明白一些了,单例就是,这个类只有个实例。

举个日常生活中的例子。

你在电脑上打开一个任务管理器,只能打开一个

还有计数器,只能有一个,不然你创建一个,他创建一个,你们记的数就不准确了

前言

单例模式是指内容中有且只会创建一个对象的设计模式,在程序中多次使用同一个对象,且作用相同,为了防止频繁的创建对象,单例模式让程序内存中创建一个对象,让所有的调用者都共享这个单例对象。单例模式的类型分为两种:懒汉式和饿汉式

饿汉式

//饿汉模式
public  class Hungry{
   /**
    *构造器私有拒绝别人创建这个对象
    */
    private Hungry(){}
    
    private final static Hungry HUNGRY=new Hungry();

    public static Hungry getInstance(){

        retrun HUNGRY;
    }
}

饿汉式会浪费空间,因为程序在启动的时候就创建好了对象,没有使用就会是的内存浪费

懒汉式

//懒汉式
public class lazySingle{

    private LazySingle(){}
    
    private static LazySingle lazySingle;

    public static LazySingle getInstance(){

        if(lazySingle==null){
            lazySingle=new LazySingle();
        }
         return lazySingle;
    }
}

但是这样会不会出现问题呢,当然在单线程的情况下是没有问题的,要是在多线程的情况下就会出现问题。就会创建很多个问题;下面就是如何解决问题

双重检查锁

//双重检查锁
public class LazySingle(){


    private LazySingle(){}

    private static LazySingle lazySingle;

    //双重检查锁
    public static LazySingle getInstance(){

        if(lazySingle==null){
            synchronized (LazySingle.class){
                if(lazySingle==null){
                    lazySingle=new LazySingle();
                }
            }
        }
        return lazySingle;
    }

}

双重检查锁,这样就可以在多线程的情况下保证数据的安全创建

volatile 防止指令重排

我们有了双重检查锁就完整了吗,会不会出现其他的问题呢,当然会有的,因为在new LazySingle()的时候,其实是有可能发生了指令重排

什么指令重排?//todo 

//双重检查锁
public class LazySingle(){


    private LazySingle(){}

    private volatile static LazySingle lazySingle;

    //双重检查锁
    public static LazySingle getInstance(){

        if(lazySingle==null){
            synchronized (LazySingle.class){
                if(lazySingle==null){
                    lazySingle=new LazySingle();
                }
            }
        }
        return lazySingle;
    }

}

静态内部类

静态内部类不是很懂 //todo

public class Holder {
 
    private Holder(){
 
    }
    public static Holder getInstance(){
        return InnerClass.HOLDER;
    }
 
    public static class InnerClass{
        private static final Holder HOLDER = new Holder();
    }
}

3.破坏单例

无论是饿汉式和还是懒汉式都是可以被破坏的。利用反射进行去破坏

    public static void main(String[] args) throws Exception {
        //通过正常方式获得对象
        LazySingle instance = LazySingle.getInstance();
        Constructor<LazySingle> declaredConstructor = LazySingle.class.getDeclaredConstructor(null);
        //可访问私有构造器
        declaredConstructor.setAccessible(true);
        //利用反射构造新对象
        LazySingle lazySingle = declaredConstructor.newInstance();
        System.out.println(instance.equals(lazySingle)); //false
    }

以上就是利用反射强制访问类的私有构造器,去创建另一个对象

今天就到这里,开始干活

单例模式介绍_IT盛夏的果实的博客-CSDN博客_单例模式目录1 前言2 单例模式类型2.1 饿汉式:2.2 懒汉式:2.2.1 双重检查锁2.2.2volatile防止指令重排2.3 静态内部类3 破坏单例1 前言单例模式是指在内存中有且只会创建一次对象的设计模式,在程序中多次使用同一个对象且作用相同的时候,为了防止频繁的创建对象,单例模式可以让程序在内存中创建一个对象,让所有的调用者都共享这一单例对象。单例模式的类型有两种:懒汉式和饿汉式。2 单例模式类型饿汉式:在类加载的时候已经创建好该单例对象。懒汉.https://blog.csdn.net/qq_50652600/article/details/123968328

我又来搞设计模式了,说反射会破坏单例,解决方案呢就是利用枚举的方式去防止被破坏。讲了一堆的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值