设计模式-单例模式

单例模式是指一个类在整个进程中只有一个实例化的对象,后续对该类的实例化都将调用已经创建好的第一个实例化对象,常用在重量级的对象中,比如sqlsession等

单例模式有好几种写法,饿汉模式,懒汉模式

复制代码
//单例模式的饿汉模式,即还没调用该对象的时候,就创建实例,
public class hungry {
  //利用类的静态变量存放在jvm的静态方法区的性质
    private static hungry hungrys=new hungry();
    //私有的无参构造函数,令外界无法new一个对象
    private hungry(){
        System.out.println("懒汉模式构造了函数");
    }
    public static hungry getHungrys(){
        return hungrys;
    }

}
复制代码

对该函数进行两次调用,发现构造函数只打印了一次,说明对象只实例化了一次,

复制代码
//懒汉模式,只有当第一个实例化对象的时候才会创建出来
public class lazy {
    private static lazy lazys=null;
    private lazy(){
        
    }
//只有在调用该方法时才会产生一个对象
//只有lazys为空的时候才会给他分配一个对象,不然直接返回,在多线程时不安全,需要加锁 .为了线程安全,不产生多个对象,对单例进行两次判空,如果只进行一次判空当两个线程同时到达锁的位置,会进行两次实例化
public static lazy getInstance(){ 

if (lazys == null)
synchronized (lazy.class)
{
if (lazys == null)
lazys
= new lazy(); }

return lazys; } }
复制代码

懒汉模式,重点在于加锁,懒汉模式是线程不安全的,需要进行加锁,并且加锁后还要进行一次空的判断。为避免cpu优化指令序列,指令重排后会导致空指针异常,还要加上violate关键字,使指令按顺序执行,指令重排主要发生在新建对象时,会有两条底层指令,分别是类的初始化,以及将类的地址赋值给lazys变量,jvm指令重排可能会先将地址赋值给变量,再进行初始化,那么这个时候有进程获取singoleton对象时,会返回还未初始化的对象导致错误。

在方法上加锁称为简单懒汉式,在获取对象时加锁称为DCL双重检验加锁,静态内部类也是懒汉模式的一种,但是一定线程安全。

复制代码
//静态内部类实现懒汉模式,一定线程安全
    class innerLazy{
        static class inner{
            
            private final static innerLazy innerLazys=new innerLazy();
               
            }
            //只有调用方法时才会加载类,把内部类的静态变量放到虚拟区
            public static innerLazy getInstance() {
               return inner.innerLazys;
           }
        }
    }
复制代码

 

枚举:

复制代码
public enum Singleton {

    INSTANCE;


}
调用方法:

public class Main {

    public static void main(String[] args) {
    Singleton.INSTANCE
} } 直接通过Singleton.INSTANCE.doSomething()的方式调用即可。方便、简洁又安全。
复制代码

懒汉和饿汉都是通过构造器的私有化来保证外界无法构造实例,但是实际上可以通过反射机制直接获得类的构造器,并不安全,可以在构造器进行一次判空处理,如果当前对象不为空时抛出异常,而enum是无法通过反射获得其构造器的,所以是安全的

反序列化也会对单例模式造成破坏,反序列获得的对象,其构造器不是从类中获得,拥有其自己的方法,可以通过重写readresolve来实现,直接返回当前的对象 

readResolve:如果被反序列化的对象的类存在readResolve这个方法,他会调用这个方法来返回一个“array”,然后浅拷贝一份,作为返回值,并且无视掉反序列化的值,即使那个字节码已经被解析。

posted @   B站读研  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示