Java设计模式——单例模式(Singleton Pattern)

前言

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建(单例模式的构造函数是私有的,保证不会被其他类实例化创建)。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

饿汉模式

public class EHanMode {

    private EHanMode(){}

    private static EHanMode eHanMode = new EHanMode();

    public static EHanMode getInstance(){
        return eHanMode;
    }
}
是否懒加载:
是否多线程安全:
优点:没有加锁,执行效率较高
缺点:类加载时就初始化,浪费内存(可能后面不会用到,但是已经加载了,没有体现需要时再加载)

懒汉模式——线程不安全

public class LanHanMode {

    private static LanHanMode lanHanMode= null;
    private LanHanMode(){}

    public static LanHanMode getInstance(){
        if(lanHanMode==null){
            lanHanMode = new LanHanMode();
        }

        return lanHanMode;
    }
}
是否懒加载:
是否多线程安全:
优点:在需要时才去创建实例(懒加载),节约了内存资源
缺点:线程不安全。比如在多线程下,线程A进入判断条件后,cpu转到线程B,线程B判断lanHanMode为空,创建。然后又转到线程A,线程A又再次创建,存在多个实例

懒汉模式改良1——线程安全

public class LanHanMode1 {

    private static LanHanMode1 lanHanMode1= null;
    private LanHanMode1(){}

    /**
     * 加锁防止多线程带来的不安全
     * @return
     */
    public static synchronized LanHanMode1 getInstance(){
        if(lanHanMode1==null){
            lanHanMode1 = new LanHanMode1();
        }

        return lanHanMode1;
    }
}
是否懒加载:
是否多线程安全:
优点:即实现了懒加载,又保证了多线程并发安全
缺点:单例创建成功后,仍然排队等待获取锁,这样是没有必要的,如果多次调用getInstance(),对性能的损耗就比较大了

懒汉模式改良2——双重校验锁(DCL,即 double-checked locking)

public class LanHanMode2 {

    private LanHanMode2(){}

    private static LanHanMode2 lanHanMode2 = null;

    public LanHanMode2 getInstance(){
       if(lanHanMode2==null){
           synchronized (LanHanMode2.class){
               if(lanHanMode2==null){
                   lanHanMode2 = new LanHanMode2();
               }
           }
       }

       return lanHanMode2;
    }
}
是否懒加载:
是否多线程安全:
优点:即实现了懒加载,又保证了多线程并发安全,同步代码块外多了一层判空,第一次创建后,后面再次调用就直接返回单例对象,不会执行同步代码块,从而提高了程序性能
缺点:因为Java的指令重排优化,导致其他线程可能会获得不正确的对象(具体可以参考我的这篇文章

所以加上volatile关键字禁止指令重排序

public class LanHanMode2 {

    private LanHanMode2(){}

    private static volatile LanHanMode2 lanHanMode2 = null;

    public LanHanMode2 getInstance(){
       if(lanHanMode2==null){
           synchronized (LanHanMode2.class){
               if(lanHanMode2==null){
                   lanHanMode2 = new LanHanMode2();
               }
           }
       }

       return lanHanMode2;
    }
}

静态内部类

public class Singleton{
    private static class SingletonHolder{
        public static Singleton instance = new Singleton();
    }
    private Singleton(){}
    public static Singleton newInstance(){
        return SingletonHolder.instance;
    }
}
是否懒加载:
是否多线程安全:
描述:与饿汉模式相同,利用类加载机制,保证多线程并发安全问题。不一样的是,他在内部类中创建对象实例,这样的话,如果不使用内部类,JVM就不会加载单例类,就不会创建单例对象,实现懒加载。

枚举

public enum Singleton {
    
    //枚举元素本身就是单例
    INSTANCE;  
    
    //添加自己需要的操作
    public void whateverMethod() {  
    }  
}
是否懒加载:
是否多线程安全:
描述:它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值