Java设计模式【之】唯一的路就是正确的路 (单例模式)

准备知识

  • 解决问题的方法才是好方法
  • 有三种网上流传的懒汉式(线程安全问题、锁方法、锁代码块),太傻了,没法解释就不写了。
  • 其中4.枚举实现,语义不清晰,不推荐使用
  • JVM类加载机制保证,类的静态属性,只会在第一次加载类的时候初始化
  • 单例模式
    就是保证在整个的软件系统中,对某个类只能存在一个对象实例,比如,日期工具类
    并且该类提供取得其对象实例的方法(静态方法)。

1.静态变量(new、静态代码块)

  • 优:写法简单,类装载时实例化。不存在线程安全问题
  • 缺:非懒加载,浪费内存资源
  • 实现形式:
    形式1:私有构造函数,私有静态属性,直接new,提供获取实例静态方法。
    形式2:私有构造函数,私有静态属性,静态代码块中new,提供获取实例静态方法。

//形式1-静态常量-new
class A {
    //私有静态属性-直接初始化
    private static final A a = new A();
    //私有构造函数
    public A() {
    }
    //提供访问方法
    public static A getInstance() {
        return a;
    }
}

//形式2-静态常量-静态代码块
class B {
    //私有静态属性
    private static final B b;
    //私有构造函数
    private B() {

    }
    //静态代码块中,初始化
    static {
        b = new B();
    }
    //提供访问方法
    public static B getInstance() {
        return b;
    }
}

public class Test {
    public static void main(String[] args) {
        System.out.println(A.getInstance());
        System.out.println(B.getInstance());
    }
}

2.双重检查锁

  • 优:懒加载、线程安全
  • 缺:需要理解能力
  • 注意:需要加 volatile 关键字,禁止重排序发生。
  • 实现
    1.私有构造函数,私有静态属性
    2.方法内先写两个判断,最后一行是返回值
    3.中间加类锁

class X {
    //私有静态属性
    private static volatile X x;
    //私有构造函数
    private X() {
    }

    public static X getInstance() {
        //一重检查
        if (x == null) {

            //加锁
            synchronized (X.class) {

                //二重检查
                if (x == null) {
                    x = new X();
                }

            }
        }

        return x;
    }
}

//双重检查锁
public class Test2 {
    public static void main(String[] args) {
        System.out.println(X.getInstance());
    }
}

3.静态内部类

  • JVM类加载机制保证,类的静态属性,只会在第一次加载类的时候初始化
  • 优:懒加载,线程安全
  • 缺:代码有点多
  • 实现:
    1.先写两个类(一个普通类O,一个静态内部类P)
    2.再写两个方法,一个私有内部构造方法,一个静态的获取供实例的方法
    3.静态内部类O,写一个直接new O 的静态属性,在外部方法中返回

//1.先写两个类(一个普通类O,一个静态内部类P)
class O {
    //2.再写两个方法,一个私有内部构造方法,一个静态的获取供实例的方法
    private O() {
    }

    //1.先写两个类(一个普通类O,一个静态内部类P)
    static class P {

        //3.静态内部类O,写一个直接new O 的静态属性,在外部方法中返回
        public static final O o = new O();
    }

    //2.再写两个方法,一个私有内部构造方法,一个静态的获取供实例的方法
    public static O getInstance() {
        return P.o;
    }

}


//静态内部类
public class Test3 {
    public static void main(String[] args) {
        System.out.println(O.getInstance());
    }
}

4.枚举实现(不推荐)

  • 缺:语义不清晰,不推荐
class Test4 {

    public static void main(String[] args) {
        U.INSTANCE.ooo();
        U.AAA.ooo();
        U.BBB.ooo();

        System.out.println(U.INSTANCE);//INSTANCE
        System.out.println(U.AAA);//AAAAAA
        System.out.println(U.BBB);//BBBB

    }

}

enum U {
    INSTANCE, AAA, BBB;

    public void ooo() {
        System.out.println("uuuuu");
    }

}

《七大设计原则》

《目录:Java设计模式》

《幕》

  • 世人匆匆忙忙,只为碎银几两。
  • ~ 今 ~ ❀ ~ ❀❀❀❀❀❀❀❀❀❀ ❀❀❀❀❀❀❀❀❀❀ ❀❀❀❀❀❀❀

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长毛山顶洞人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值