【JavaEE】单例模式

为什么要有单例模式

在一个项目里,可能有一些对象是专门用来保存一些数据的,这个对象可能非常大。
可能占用内存几十个G,或者几百G,或者上千个G。
在这里插入图片描述

如果这个对象不小心再被创建一次,服务器的内存可能就被占用光了。
在这里插入图片描述
所以说,保证这个对象只有一个是一件非常重要的事。

饿汉和懒汉的意思

这里的饿汉和懒汉跟我们平时听到的并不是同一个意思。

饿汉表示急切急迫的意思。

懒汉表示不急迫从容的意思。

饿汉式实现

这种实现中是先把对象准备好的(比较急迫),所以就叫成饿汉式(Eager)。

  1. 先创建对象
  2. 将构造器私有化,防止类外创建对象
  3. 暴露一个获取对象的方法
public class SingletonEager {
    private static SingletonEager instance = new SingletonEager();

    private SingletonEager(){

    };

    public static SingletonEager getInstance() {
        return instance;
    }
}
  • 在多线程的情况下,饿汉式实现不会涉及到变量的修改操作,所以是线程安全的。

饿汉式测试:

public class Test {
    public static void main(String[] args) {
        SingletonEager instance = SingletonEager.getInstance();
        SingletonEager instance2 = SingletonEager.getInstance();
        System.out.println(instance == instance2);
    }
}

输出:
在这里插入图片描述

懒汉式实现

懒汉式(Lazy)跟饿汉式不同,当调用获取对象的方法时,才会创建一个对象。

代码:

public class SingletonLazy {
    public static SingletonLazy obj = null;

    private SingletonLazy(){

    };

    public static SingletonLazy getInstance() {
        if (obj == null) {
            obj = new SingletonLazy();
        }
        return obj;
    }

}

但是这不是线程安全的,因为当多个线程同时调用getInstance方法的时候,就有可能创建无数多个对象。
下图以两个线程为例子:
在这里插入图片描述

  • 上图就表示了,多个线程执行这段代码的时候就有可能创建多个对象,所以要上锁。在这里要对整个if代码块上锁。

代码如下:

public static SingletonLazy getInstance() {
        synchronized(lock) {
            if (obj == null) {
                obj = new SingletonLazy();
            }
        }
        return obj;
    }
  • 但是呢,如果有很多线程同时调用这个方法,而且当obj != null 时,对于上面的代码会导致很多线程都阻塞了。
  • 然而obj != null时并不会执行创建对象的操作,只执行return obj,此时线程是安全的,所以再进行一次判断。
  • 只有当obj == null的时候才执行synchronized(lock){....}

代码:

public static SingletonLazy getInstance() {
        if (obj == null) {
            synchronized(lock) {
                if (obj == null) {
                    obj = new SingletonLazy();
                }
            }
        }

        return obj;
    }

测试懒汉式:

public class Test2 {
    public static void main(String[] args) {
        SingletonLazy instance = SingletonLazy.getInstance();
        SingletonLazy instance2 = SingletonLazy.getInstance();
        System.out.println(instance == instance2);
    }
}

结果:
在这里插入图片描述

关于单例模式的实现方式并不止懒汉式饿汉式这两种,其他的暂时不做拓展,懒汉式饿汉式是很经典的两种实现方式,先把这两种掌握,之后遇到其他的实现方式再做拓展。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值