java-单例设计模式

单例模式

双重检验(懒汉式DCL)

  • 使用双重检查,提高效率,和线程安全性
  • instance记得使用volatile
    • instance = new Singleton()做了三件事:
      1. 给 instance 分配内存
      2. 调用 Singleton 的构造函数来初始化成员变量
      3. 将instance对象指向分配的内存空间(执行完这步 instance 就为非 null 了)
    • 第2步和第3步可能重排序,一旦按照132执行,很有可能执行到3后线程被抢,然后判断instance不为空就返回,后面使用时报空指针
    • 所以使用volatile防止重排序,无论是123执行还是132执行,确保读操作不会再写操作之前(happens-before原则)。
    • jdk5之前的还是回存在问题,jdk本身有bug

为什么需要添加volatile:http://wuchong.me/blog/2014/08/28/how-to-correctly-write-singleton-pattern/#comments

public class Singleton {
//注意(volatile static)
    private volatile static Singleton instance; //声明成 volatile
    private Singleton (){}
    public static Singleton getSingleton() {
        if (instance == null) {                         
            synchronized (Singleton.class) {
                if (instance == null) {       
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
   
}

饿汉式

  • 类加载的时候就将实例处理初始化好
class Util{
    private Util(){
        System.out.println("Util init");
    }
    private static Util util = new Util();
    public static Util getUtil(){
        return util;
    }
}

静态内部类(推荐)

https://blog.csdn.net/mnb65482/article/details/80458571

public class InnerClassMethod {

    private InnerClassMethod(){}

//    static: 可以直接访问(注意:static)
    public static InnerClassMethod getInstance(){
//        内部类在使用的时候才会加载类
        return InnerClass.instance;
    }

//    使用静态内部类,使得不用实例化可以直接访问(注意:static)
    private static class InnerClass{
//        类加载后初始化,内部类可以直接访问外部方法(注意:private final)
        private final static InnerClassMethod instance=new InnerClassMethod();
    }
}

枚举方法(推荐)

// 枚举实例在创建的时候是安全的
public enum EnumMethod {
    INSTANCE
    ;
    private int count=0;
    public int getCountAndIncrease(){
        count++;
        return count;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值